dlib 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +3 -0
- data/Gemfile +9 -0
- data/Rakefile +8 -0
- data/examples/find_candidate_object_locations.rb +5 -1
- data/ext/dlib/depend +2 -1
- data/ext/dlib/dlib.cpp +2 -0
- data/ext/dlib/extconf.rb +2 -0
- data/ext/dlib/image.inc +53 -0
- data/ext/dlib/missing.c +107 -0
- data/ext/dlib/missing.h +26 -0
- data/ext/dlib/rectangle.inc +174 -2
- data/lib/dlib/version.rb +1 -1
- data/spec/dlib/rectangle_spec.rb +120 -0
- data/spec/spec_helper.rb +94 -0
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de7377ee20f24dfad880d3c6ff16109fc80e8f87
|
4
|
+
data.tar.gz: adadbe9e0d6cd190fe998cd71e56bd1900233236
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8539bb6d4128233ede76cbd266ea36962922244a56b9fb6177bccc898a45831d41cd73e9249ec8ccb4587fc58814d65f252477ba0e3e775239b8e94f7cfc61d3
|
7
|
+
data.tar.gz: 56a2fb4457ce28a6a3bacf875f083746d08d5a35cc9e181842a8b3d8cfd647c656af717d83512e8b81d1178c432f3125b420f5915e1afe82a2639a336bf27840
|
data/.rspec
ADDED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -7,5 +7,9 @@ rects = Dlib.find_candidate_object_locations(img, min_size: 500)
|
|
7
7
|
|
8
8
|
puts "number of rectangles found #{rects.length}"
|
9
9
|
rects.each.with_index do |rect, index|
|
10
|
-
puts "Detection #{index}: Left: #{rect.left} Top: #{rect.top} Right: #{rect.right} Bottom: #{rect.bottom}"
|
10
|
+
puts "Detection #{index}: Left: #{rect.left} Top: #{rect.top} Right: #{rect.right} Bottom: #{rect.bottom} Area: #{rect.area}"
|
11
|
+
img.draw_rectangle!(rect, [0, 0, 255]) if rect.area > 0
|
11
12
|
end
|
13
|
+
|
14
|
+
output_file = ARGV[1] || 'marked.jpg'
|
15
|
+
img.save_jpeg(output_file)
|
data/ext/dlib/depend
CHANGED
data/ext/dlib/dlib.cpp
CHANGED
data/ext/dlib/extconf.rb
CHANGED
data/ext/dlib/image.inc
CHANGED
@@ -86,6 +86,55 @@ dlib_rb_image_nc(VALUE image)
|
|
86
86
|
return LONG2NUM(nc);
|
87
87
|
}
|
88
88
|
|
89
|
+
extern "C" VALUE
|
90
|
+
dlib_rb_image_save_jpeg(VALUE image, VALUE filename)
|
91
|
+
{
|
92
|
+
rgb_image_container *image_container = dlib_rb_image_get_rgb_image_container(image);
|
93
|
+
|
94
|
+
dlib::save_jpeg(image_container->image, StringValueCStr(filename) /*, quality */);
|
95
|
+
|
96
|
+
return image;
|
97
|
+
}
|
98
|
+
|
99
|
+
extern "C" VALUE
|
100
|
+
dlib_rb_image_draw_rectangle(int argc, VALUE *argv, VALUE image)
|
101
|
+
{
|
102
|
+
rgb_image_container *image_container = dlib_rb_image_get_rgb_image_container(image);
|
103
|
+
|
104
|
+
VALUE rect, pixel, thickness_v;
|
105
|
+
rb_scan_args(argc, argv, "21", &rect, &pixel, &thickness_v);
|
106
|
+
|
107
|
+
if (!is_obj_dlib_rectangle(rect)) {
|
108
|
+
rb_raise(rb_eTypeError, "Invalid rectangle is given: %"PRIsVALUE, rect);
|
109
|
+
}
|
110
|
+
|
111
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
112
|
+
|
113
|
+
Check_Type(pixel, T_ARRAY);
|
114
|
+
if (RARRAY_LEN(pixel) != 3) {
|
115
|
+
rb_raise(rb_eArgError, "Invalid pixel value is given: %"PRIsVALUE, pixel);
|
116
|
+
}
|
117
|
+
|
118
|
+
unsigned char red = static_cast<unsigned char>(NUM2UINT(RARRAY_AREF(pixel, 0)));
|
119
|
+
unsigned char green = static_cast<unsigned char>(NUM2UINT(RARRAY_AREF(pixel, 1)));
|
120
|
+
unsigned char blue = static_cast<unsigned char>(NUM2UINT(RARRAY_AREF(pixel, 2)));
|
121
|
+
|
122
|
+
unsigned int thickness = 1;
|
123
|
+
if (!NIL_P(thickness_v)) {
|
124
|
+
Check_Type(thickness_v, T_FIXNUM);
|
125
|
+
thickness = FIX2UINT(thickness_v);
|
126
|
+
}
|
127
|
+
|
128
|
+
dlib::draw_rectangle(
|
129
|
+
image_container->image,
|
130
|
+
rectcont->rect,
|
131
|
+
dlib::rgb_pixel(red, green, blue),
|
132
|
+
thickness
|
133
|
+
);
|
134
|
+
|
135
|
+
return image;
|
136
|
+
}
|
137
|
+
|
89
138
|
static void
|
90
139
|
Init_dlib_image()
|
91
140
|
{
|
@@ -98,4 +147,8 @@ Init_dlib_image()
|
|
98
147
|
|
99
148
|
rb_define_method(cDlibImage, "nr", RUBY_METHOD_FUNC(dlib_rb_image_nr), 0);
|
100
149
|
rb_define_method(cDlibImage, "nc", RUBY_METHOD_FUNC(dlib_rb_image_nc), 0);
|
150
|
+
|
151
|
+
rb_define_method(cDlibImage, "save_jpeg", RUBY_METHOD_FUNC(dlib_rb_image_save_jpeg), 1);
|
152
|
+
|
153
|
+
rb_define_method(cDlibImage, "draw_rectangle!", RUBY_METHOD_FUNC(dlib_rb_image_draw_rectangle), -1);
|
101
154
|
}
|
data/ext/dlib/missing.c
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
#ifndef HAVE_RB_GET_KWARGS
|
2
|
+
|
3
|
+
#include "missing.h"
|
4
|
+
|
5
|
+
static VALUE
|
6
|
+
rb_keyword_error_new(const char *error, VALUE keys)
|
7
|
+
{
|
8
|
+
const char *msg = "";
|
9
|
+
VALUE error_message;
|
10
|
+
|
11
|
+
if (RARRAY_LEN(keys) == 1) {
|
12
|
+
keys = RARRAY_AREF(keys, 0);
|
13
|
+
}
|
14
|
+
else {
|
15
|
+
keys = rb_ary_join(keys, rb_usascii_str_new2(", "));
|
16
|
+
msg = "s";
|
17
|
+
}
|
18
|
+
|
19
|
+
error_message = rb_sprintf("%s keyword%s: %"PRIsVALUE, error, msg, keys);
|
20
|
+
|
21
|
+
return rb_exc_new_str(rb_eArgError, error_message);
|
22
|
+
}
|
23
|
+
|
24
|
+
NORETURN(static void rb_keyword_error(const char *error, VALUE keys));
|
25
|
+
static void
|
26
|
+
rb_keyword_error(const char *error, VALUE keys)
|
27
|
+
{
|
28
|
+
rb_exc_raise(rb_keyword_error_new(error, keys));
|
29
|
+
}
|
30
|
+
|
31
|
+
NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords));
|
32
|
+
static void
|
33
|
+
unknown_keyword_error(VALUE hash, const ID *table, int keywords)
|
34
|
+
{
|
35
|
+
st_table *tbl = rb_hash_tbl(hash);
|
36
|
+
VALUE keys;
|
37
|
+
int i;
|
38
|
+
for (i = 0; i < keywords; i++) {
|
39
|
+
st_data_t key = ID2SYM(table[i]);
|
40
|
+
st_delete(tbl, &key, NULL);
|
41
|
+
}
|
42
|
+
keys = rb_funcall(hash, rb_intern("keys"), 0, 0);
|
43
|
+
if (!RB_TYPE_P(keys, T_ARRAY)) rb_raise(rb_eArgError, "unknown keyword");
|
44
|
+
rb_keyword_error("unknown", keys);
|
45
|
+
}
|
46
|
+
|
47
|
+
int
|
48
|
+
rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
|
49
|
+
{
|
50
|
+
int i = 0, j;
|
51
|
+
int rest = 0;
|
52
|
+
VALUE missing = Qnil;
|
53
|
+
st_data_t key;
|
54
|
+
|
55
|
+
#define extract_kwarg(keyword, val) \
|
56
|
+
(key = (st_data_t)(keyword), values ? \
|
57
|
+
st_delete(rb_hash_tbl(keyword_hash), &key, (val)) : \
|
58
|
+
st_lookup(rb_hash_tbl(keyword_hash), key, (val)))
|
59
|
+
|
60
|
+
if (NIL_P(keyword_hash)) keyword_hash = 0;
|
61
|
+
|
62
|
+
if (optional < 0) {
|
63
|
+
rest = 1;
|
64
|
+
optional = -1-optional;
|
65
|
+
}
|
66
|
+
if (values) {
|
67
|
+
for (j = 0; j < required + optional; j++) {
|
68
|
+
values[j] = Qundef;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
if (required) {
|
72
|
+
for (; i < required; i++) {
|
73
|
+
VALUE keyword = ID2SYM(table[i]);
|
74
|
+
if (keyword_hash) {
|
75
|
+
st_data_t val;
|
76
|
+
if (extract_kwarg(keyword, &val)) {
|
77
|
+
if (values) values[i] = (VALUE)val;
|
78
|
+
continue;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
if (NIL_P(missing)) missing = rb_ary_tmp_new(1);
|
82
|
+
rb_ary_push(missing, keyword);
|
83
|
+
}
|
84
|
+
if (!NIL_P(missing)) {
|
85
|
+
rb_keyword_error("missing", missing);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
j = i;
|
89
|
+
if (optional && keyword_hash) {
|
90
|
+
for (i = 0; i < optional; i++) {
|
91
|
+
st_data_t val;
|
92
|
+
if (extract_kwarg(ID2SYM(table[required+i]), &val)) {
|
93
|
+
if (values) values[required+i] = (VALUE)val;
|
94
|
+
j++;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
if (!rest && keyword_hash) {
|
99
|
+
if (RHASH_SIZE(keyword_hash) > (unsigned int)j) {
|
100
|
+
unknown_keyword_error(keyword_hash, table, required+optional);
|
101
|
+
}
|
102
|
+
}
|
103
|
+
return j;
|
104
|
+
#undef extract_kwarg
|
105
|
+
}
|
106
|
+
|
107
|
+
#endif /* HAVE_RB_GET_KWARGS */
|
data/ext/dlib/missing.h
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#ifndef DLIB_MISSING_H
|
2
|
+
#define DLIB_MISSING_H
|
3
|
+
|
4
|
+
#include <ruby/ruby.h>
|
5
|
+
|
6
|
+
#if defined(__cplusplus)
|
7
|
+
extern "C" {
|
8
|
+
#if 0
|
9
|
+
} /* satisfy cc-mode */
|
10
|
+
#endif
|
11
|
+
#endif
|
12
|
+
|
13
|
+
|
14
|
+
#ifndef HAVE_RB_GET_KWARGS
|
15
|
+
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values);
|
16
|
+
#endif
|
17
|
+
|
18
|
+
|
19
|
+
#if defined(__cplusplus)
|
20
|
+
#if 0
|
21
|
+
{ /* satisfy cc-mode */
|
22
|
+
#endif
|
23
|
+
} /* extern "C" { */
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#endif /* DLIB_MISSING_H */
|
data/ext/dlib/rectangle.inc
CHANGED
@@ -30,6 +30,9 @@ static const rb_data_type_t rectangle_container_data_type = {
|
|
30
30
|
#endif
|
31
31
|
};
|
32
32
|
|
33
|
+
#define is_data_rectangle(obj) (RTYPEDDATA_P((obj)) && RTYPEDDATA_TYPE((obj)) == &rectangle_container_data_type)
|
34
|
+
#define is_obj_dlib_rectangle(obj) (RB_TYPE_P((obj), T_DATA) && is_data_rectangle(obj))
|
35
|
+
|
33
36
|
static rectangle_container *
|
34
37
|
dlib_rb_rectangle_get_rectangle_container(VALUE rect)
|
35
38
|
{
|
@@ -49,14 +52,66 @@ dlib_rb_rectangle_alloc(VALUE klass)
|
|
49
52
|
}
|
50
53
|
|
51
54
|
static VALUE
|
52
|
-
|
55
|
+
dlib_rb_rectangle_s_new(VALUE klass, dlib::rectangle const &dlib_rect)
|
53
56
|
{
|
54
|
-
VALUE rect = dlib_rb_rectangle_alloc(
|
57
|
+
VALUE rect = dlib_rb_rectangle_alloc(klass);
|
55
58
|
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
56
59
|
rectcont->rect = dlib_rect;
|
57
60
|
return rect;
|
58
61
|
}
|
59
62
|
|
63
|
+
static VALUE
|
64
|
+
dlib_rb_rectangle_new(dlib::rectangle const &dlib_rect)
|
65
|
+
{
|
66
|
+
return dlib_rb_rectangle_s_new(cDlibRectangle, dlib_rect);
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE
|
70
|
+
dlib_rb_rectangle_initialize(int argc, VALUE* argv, VALUE rect)
|
71
|
+
{
|
72
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
73
|
+
|
74
|
+
switch (argc) {
|
75
|
+
case 4: {
|
76
|
+
long left, top, right, bottom;
|
77
|
+
left = NUM2LONG(argv[0]);
|
78
|
+
top = NUM2LONG(argv[1]);
|
79
|
+
right = NUM2LONG(argv[2]);
|
80
|
+
bottom = NUM2LONG(argv[3]);
|
81
|
+
rectcont->rect = dlib::rectangle(left, top, right, bottom);
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
|
85
|
+
case 2: {
|
86
|
+
unsigned long width, height;
|
87
|
+
width = NUM2ULONG(argv[0]);
|
88
|
+
height = NUM2ULONG(argv[1]);
|
89
|
+
rectcont->rect = dlib::rectangle(width, height);
|
90
|
+
break;
|
91
|
+
}
|
92
|
+
|
93
|
+
case 0:
|
94
|
+
// Nothing to do.
|
95
|
+
break;
|
96
|
+
|
97
|
+
default:
|
98
|
+
rb_raise(rb_eArgError, "Irregal number of arguments are given");
|
99
|
+
}
|
100
|
+
|
101
|
+
return rect;
|
102
|
+
}
|
103
|
+
|
104
|
+
extern "C" VALUE
|
105
|
+
dlib_rb_rectangle_eq(VALUE rect, VALUE other)
|
106
|
+
{
|
107
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
108
|
+
if (is_obj_dlib_rectangle(other)) {
|
109
|
+
rectangle_container *rectcont_other = dlib_rb_rectangle_get_rectangle_container(other);
|
110
|
+
return rectcont->rect == rectcont_other->rect ? Qtrue : Qfalse;
|
111
|
+
}
|
112
|
+
return Qfalse;
|
113
|
+
}
|
114
|
+
|
60
115
|
extern "C" VALUE
|
61
116
|
dlib_rb_rectangle_left(VALUE rect)
|
62
117
|
{
|
@@ -85,6 +140,105 @@ dlib_rb_rectangle_bottom(VALUE rect)
|
|
85
140
|
return LONG2NUM(rectcont->rect.bottom());
|
86
141
|
}
|
87
142
|
|
143
|
+
extern "C" VALUE
|
144
|
+
dlib_rb_rectangle_width(VALUE rect)
|
145
|
+
{
|
146
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
147
|
+
return ULONG2NUM(rectcont->rect.width());
|
148
|
+
}
|
149
|
+
|
150
|
+
extern "C" VALUE
|
151
|
+
dlib_rb_rectangle_height(VALUE rect)
|
152
|
+
{
|
153
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
154
|
+
return ULONG2NUM(rectcont->rect.height());
|
155
|
+
}
|
156
|
+
|
157
|
+
extern "C" VALUE
|
158
|
+
dlib_rb_rectangle_area(VALUE rect)
|
159
|
+
{
|
160
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
161
|
+
return ULONG2NUM(rectcont->rect.area());
|
162
|
+
}
|
163
|
+
|
164
|
+
extern "C" VALUE
|
165
|
+
dlib_rb_rectangle_is_empty(VALUE rect)
|
166
|
+
{
|
167
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
168
|
+
return rectcont->rect.is_empty() ? Qtrue : Qfalse;
|
169
|
+
}
|
170
|
+
|
171
|
+
extern "C" VALUE
|
172
|
+
dlib_rb_rectangle_set_left(VALUE rect, VALUE val)
|
173
|
+
{
|
174
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
175
|
+
rectcont->rect.set_left(NUM2LONG(val));
|
176
|
+
return val;
|
177
|
+
}
|
178
|
+
|
179
|
+
extern "C" VALUE
|
180
|
+
dlib_rb_rectangle_set_top(VALUE rect, VALUE val)
|
181
|
+
{
|
182
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
183
|
+
rectcont->rect.set_top(NUM2LONG(val));
|
184
|
+
return val;
|
185
|
+
}
|
186
|
+
|
187
|
+
extern "C" VALUE
|
188
|
+
dlib_rb_rectangle_set_right(VALUE rect, VALUE val)
|
189
|
+
{
|
190
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
191
|
+
rectcont->rect.set_right(NUM2LONG(val));
|
192
|
+
return val;
|
193
|
+
}
|
194
|
+
|
195
|
+
extern "C" VALUE
|
196
|
+
dlib_rb_rectangle_set_bottom(VALUE rect, VALUE val)
|
197
|
+
{
|
198
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
199
|
+
rectcont->rect.set_bottom(NUM2LONG(val));
|
200
|
+
return val;
|
201
|
+
}
|
202
|
+
|
203
|
+
extern "C" VALUE
|
204
|
+
dlib_rb_rectangle_union(VALUE rect1, VALUE rect2)
|
205
|
+
{
|
206
|
+
rectangle_container *rectcont1 = dlib_rb_rectangle_get_rectangle_container(rect1);
|
207
|
+
rectangle_container *rectcont2 = dlib_rb_rectangle_get_rectangle_container(rect2);
|
208
|
+
dlib::rectangle dlib_rect3 = rectcont1->rect + rectcont2->rect;
|
209
|
+
return dlib_rb_rectangle_s_new(CLASS_OF(rect1), dlib_rect3);
|
210
|
+
}
|
211
|
+
|
212
|
+
extern "C" VALUE
|
213
|
+
dlib_rb_rectangle_intersect(VALUE rect1, VALUE rect2)
|
214
|
+
{
|
215
|
+
rectangle_container *rectcont1 = dlib_rb_rectangle_get_rectangle_container(rect1);
|
216
|
+
rectangle_container *rectcont2 = dlib_rb_rectangle_get_rectangle_container(rect2);
|
217
|
+
dlib::rectangle dlib_rect3 = rectcont1->rect.intersect(rectcont2->rect);
|
218
|
+
return dlib_rb_rectangle_s_new(CLASS_OF(rect1), dlib_rect3);
|
219
|
+
}
|
220
|
+
|
221
|
+
extern "C" VALUE
|
222
|
+
dlib_rb_rectangle_inspect(VALUE rect)
|
223
|
+
{
|
224
|
+
rectangle_container *rectcont = dlib_rb_rectangle_get_rectangle_container(rect);
|
225
|
+
|
226
|
+
VALUE cname = rb_class_name(CLASS_OF(rect));
|
227
|
+
VALUE str = rb_sprintf(
|
228
|
+
"#<%"PRIsVALUE" (%ld, %ld)-(%ld, %ld) %lux%lu%s>",
|
229
|
+
cname,
|
230
|
+
rectcont->rect.left(),
|
231
|
+
rectcont->rect.top(),
|
232
|
+
rectcont->rect.right(),
|
233
|
+
rectcont->rect.bottom(),
|
234
|
+
rectcont->rect.width(),
|
235
|
+
rectcont->rect.height(),
|
236
|
+
(rectcont->rect.is_empty() ? " empty" : "")
|
237
|
+
);
|
238
|
+
|
239
|
+
return str;
|
240
|
+
}
|
241
|
+
|
88
242
|
static void
|
89
243
|
Init_dlib_rectangle()
|
90
244
|
{
|
@@ -92,8 +246,26 @@ Init_dlib_rectangle()
|
|
92
246
|
|
93
247
|
rb_define_alloc_func(cDlibRectangle, dlib_rb_rectangle_alloc);
|
94
248
|
|
249
|
+
rb_define_method(cDlibRectangle, "initialize", RUBY_METHOD_FUNC(dlib_rb_rectangle_initialize), -1);
|
250
|
+
|
251
|
+
rb_define_method(cDlibRectangle, "==", RUBY_METHOD_FUNC(dlib_rb_rectangle_eq), 1);
|
252
|
+
|
95
253
|
rb_define_method(cDlibRectangle, "left", RUBY_METHOD_FUNC(dlib_rb_rectangle_left), 0);
|
96
254
|
rb_define_method(cDlibRectangle, "top", RUBY_METHOD_FUNC(dlib_rb_rectangle_top), 0);
|
97
255
|
rb_define_method(cDlibRectangle, "right", RUBY_METHOD_FUNC(dlib_rb_rectangle_right), 0);
|
98
256
|
rb_define_method(cDlibRectangle, "bottom", RUBY_METHOD_FUNC(dlib_rb_rectangle_bottom), 0);
|
257
|
+
rb_define_method(cDlibRectangle, "width", RUBY_METHOD_FUNC(dlib_rb_rectangle_width), 0);
|
258
|
+
rb_define_method(cDlibRectangle, "height", RUBY_METHOD_FUNC(dlib_rb_rectangle_height), 0);
|
259
|
+
rb_define_method(cDlibRectangle, "area", RUBY_METHOD_FUNC(dlib_rb_rectangle_area), 0);
|
260
|
+
rb_define_method(cDlibRectangle, "empty?", RUBY_METHOD_FUNC(dlib_rb_rectangle_is_empty), 0);
|
261
|
+
|
262
|
+
rb_define_method(cDlibRectangle, "left=", RUBY_METHOD_FUNC(dlib_rb_rectangle_set_left), 1);
|
263
|
+
rb_define_method(cDlibRectangle, "top=", RUBY_METHOD_FUNC(dlib_rb_rectangle_set_top), 1);
|
264
|
+
rb_define_method(cDlibRectangle, "right=", RUBY_METHOD_FUNC(dlib_rb_rectangle_set_right), 1);
|
265
|
+
rb_define_method(cDlibRectangle, "bottom=", RUBY_METHOD_FUNC(dlib_rb_rectangle_set_bottom), 1);
|
266
|
+
|
267
|
+
rb_define_method(cDlibRectangle, "+", RUBY_METHOD_FUNC(dlib_rb_rectangle_union), 1);
|
268
|
+
rb_define_method(cDlibRectangle, "intersect", RUBY_METHOD_FUNC(dlib_rb_rectangle_intersect), 1);
|
269
|
+
|
270
|
+
rb_define_method(cDlibRectangle, "inspect", RUBY_METHOD_FUNC(dlib_rb_rectangle_inspect), 0);
|
99
271
|
}
|
data/lib/dlib/version.rb
CHANGED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dlib
|
4
|
+
describe Rectangle do
|
5
|
+
def rectangle(*args)
|
6
|
+
described_class.new(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
subject { rectangle(1, 2, 3, 4) }
|
10
|
+
|
11
|
+
describe '#initialize' do
|
12
|
+
context 'with left, top, right, and bottom positions' do
|
13
|
+
it 'has correct values' do
|
14
|
+
expect(subject.left).to eq(1)
|
15
|
+
expect(subject.top).to eq(2)
|
16
|
+
expect(subject.right).to eq(3)
|
17
|
+
expect(subject.bottom).to eq(4)
|
18
|
+
expect(subject.width).to eq(3)
|
19
|
+
expect(subject.height).to eq(3)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with width and height' do
|
24
|
+
subject { rectangle(2, 3) }
|
25
|
+
|
26
|
+
it 'has correct values' do
|
27
|
+
expect(subject.left).to eq(0)
|
28
|
+
expect(subject.top).to eq(0)
|
29
|
+
expect(subject.right).to eq(1)
|
30
|
+
expect(subject.bottom).to eq(2)
|
31
|
+
expect(subject.width).to eq(2)
|
32
|
+
expect(subject.height).to eq(3)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'without arguments' do
|
37
|
+
subject { rectangle() }
|
38
|
+
|
39
|
+
it 'has correct values' do
|
40
|
+
expect(subject.left).to eq(0)
|
41
|
+
expect(subject.top).to eq(0)
|
42
|
+
expect(subject.right).to eq(-1)
|
43
|
+
expect(subject.bottom).to eq(-1)
|
44
|
+
expect(subject.width).to eq(0)
|
45
|
+
expect(subject.height).to eq(0)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#left=' do
|
51
|
+
it 'set left value' do
|
52
|
+
subject.left = 42
|
53
|
+
expect(subject.left).to eq(42)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#top=' do
|
58
|
+
it 'set top value' do
|
59
|
+
subject.top = 42
|
60
|
+
expect(subject.top).to eq(42)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#right=' do
|
65
|
+
it 'set right value' do
|
66
|
+
subject.right = 42
|
67
|
+
expect(subject.right).to eq(42)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#bottom=' do
|
72
|
+
it 'set bottom value' do
|
73
|
+
subject.bottom = 42
|
74
|
+
expect(subject.bottom).to eq(42)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#area' do
|
79
|
+
it 'returns collect values' do
|
80
|
+
expect(rectangle(1, 2, 3, 4).area).to eq(9)
|
81
|
+
expect(rectangle(4, 4).area).to eq(16)
|
82
|
+
expect(rectangle().area).to eq(0)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#empty?' do
|
87
|
+
it 'returns collect values' do
|
88
|
+
expect(rectangle(1, 2, 3, 4)).not_to be_empty
|
89
|
+
expect(rectangle(4, 4)).not_to be_empty
|
90
|
+
expect(rectangle()).to be_empty
|
91
|
+
end
|
92
|
+
|
93
|
+
specify 'There are different empty rectangles not to be equal' do
|
94
|
+
r1 = rectangle(1, 1, 3, 3).intersect(rectangle())
|
95
|
+
r2 = rectangle()
|
96
|
+
expect(r1).not_to eq(r2)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#+' do
|
101
|
+
it 'returns union of two rectangles' do
|
102
|
+
expect(rectangle(1, 1, 3, 3) + rectangle(2, 2, 5, 5)).to eq(rectangle(1, 1, 5, 5))
|
103
|
+
expect(rectangle(1, 2, 3, 5) + rectangle(2, 1, 5, 3)).to eq(rectangle(1, 1, 5, 5))
|
104
|
+
expect(rectangle(1, 1, 3, 3) + rectangle()).to eq(rectangle(1, 1, 3, 3))
|
105
|
+
expect(rectangle() + rectangle(1, 1, 3, 3)).to eq(rectangle(1, 1, 3, 3))
|
106
|
+
expect(rectangle() + rectangle()).to eq(rectangle())
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#intersect' do
|
111
|
+
it 'returns intersection of two rectangles' do
|
112
|
+
expect(rectangle(1, 1, 5, 5).intersect(rectangle(2, 2, 3, 3))).to eq(rectangle(2, 2, 3, 3))
|
113
|
+
expect(rectangle(1, 1, 3, 3).intersect(rectangle(2, 2, 5, 5))).to eq(rectangle(2, 2, 3, 3))
|
114
|
+
expect(rectangle(1, 1, 3, 3).intersect(rectangle())).to be_empty
|
115
|
+
expect(rectangle().intersect(rectangle(1, 1, 3, 3))).to be_empty
|
116
|
+
expect(rectangle().intersect(rectangle())).to be_empty
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
16
|
+
# users commonly want.
|
17
|
+
#
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
19
|
+
|
20
|
+
require 'dlib'
|
21
|
+
|
22
|
+
RSpec.configure do |config|
|
23
|
+
# rspec-expectations config goes here. You can use an alternate
|
24
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
25
|
+
# assertions if you prefer.
|
26
|
+
config.expect_with :rspec do |expectations|
|
27
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
28
|
+
# and `failure_message` of custom matchers include text for helper methods
|
29
|
+
# defined using `chain`, e.g.:
|
30
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
31
|
+
# # => "be bigger than 2 and smaller than 4"
|
32
|
+
# ...rather than:
|
33
|
+
# # => "be bigger than 2"
|
34
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
35
|
+
end
|
36
|
+
|
37
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
38
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
39
|
+
config.mock_with :rspec do |mocks|
|
40
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
41
|
+
# a real object. This is generally recommended, and will default to
|
42
|
+
# `true` in RSpec 4.
|
43
|
+
mocks.verify_partial_doubles = true
|
44
|
+
end
|
45
|
+
|
46
|
+
# The settings below are suggested to provide a good initial experience
|
47
|
+
# with RSpec, but feel free to customize to your heart's content.
|
48
|
+
=begin
|
49
|
+
# These two settings work together to allow you to limit a spec run
|
50
|
+
# to individual examples or groups you care about by tagging them with
|
51
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
52
|
+
# get run.
|
53
|
+
config.filter_run :focus
|
54
|
+
config.run_all_when_everything_filtered = true
|
55
|
+
|
56
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
57
|
+
# recommended. For more details, see:
|
58
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
59
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
60
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
61
|
+
config.disable_monkey_patching!
|
62
|
+
|
63
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
64
|
+
# be too noisy due to issues in dependencies.
|
65
|
+
config.warnings = true
|
66
|
+
|
67
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
68
|
+
# file, and it's useful to allow more verbose output when running an
|
69
|
+
# individual spec file.
|
70
|
+
if config.files_to_run.one?
|
71
|
+
# Use the documentation formatter for detailed output,
|
72
|
+
# unless a formatter has already been configured
|
73
|
+
# (e.g. via a command-line flag).
|
74
|
+
config.default_formatter = 'doc'
|
75
|
+
end
|
76
|
+
|
77
|
+
# Print the 10 slowest examples and example groups at the
|
78
|
+
# end of the spec run, to help surface which specs are running
|
79
|
+
# particularly slow.
|
80
|
+
config.profile_examples = 10
|
81
|
+
|
82
|
+
# Run specs in random order to surface order dependencies. If you find an
|
83
|
+
# order dependency and want to debug it, you can fix the order by providing
|
84
|
+
# the seed, which is printed after each run.
|
85
|
+
# --seed 1234
|
86
|
+
config.order = :random
|
87
|
+
|
88
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
89
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
90
|
+
# test failures related to randomization by passing the same `--seed` value
|
91
|
+
# as the one that triggered the failure.
|
92
|
+
Kernel.srand config.seed
|
93
|
+
=end
|
94
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dlib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02
|
11
|
+
date: 2015-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -47,6 +47,7 @@ extensions:
|
|
47
47
|
extra_rdoc_files: []
|
48
48
|
files:
|
49
49
|
- ".gitignore"
|
50
|
+
- ".rspec"
|
50
51
|
- Gemfile
|
51
52
|
- LICENSE.txt
|
52
53
|
- README.md
|
@@ -2938,8 +2939,12 @@ files:
|
|
2938
2939
|
- ext/dlib/find_candidate_object_locations.inc
|
2939
2940
|
- ext/dlib/geometry.inc
|
2940
2941
|
- ext/dlib/image.inc
|
2942
|
+
- ext/dlib/missing.c
|
2943
|
+
- ext/dlib/missing.h
|
2941
2944
|
- ext/dlib/rectangle.inc
|
2942
2945
|
- lib/dlib/version.rb
|
2946
|
+
- spec/dlib/rectangle_spec.rb
|
2947
|
+
- spec/spec_helper.rb
|
2943
2948
|
homepage: ''
|
2944
2949
|
licenses:
|
2945
2950
|
- MIT
|
@@ -2964,4 +2969,6 @@ rubygems_version: 2.4.5
|
|
2964
2969
|
signing_key:
|
2965
2970
|
specification_version: 4
|
2966
2971
|
summary: Ruby bindings of dlib C++ library.
|
2967
|
-
test_files:
|
2972
|
+
test_files:
|
2973
|
+
- spec/dlib/rectangle_spec.rb
|
2974
|
+
- spec/spec_helper.rb
|