afeld-opencv 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. data/.gitignore +23 -0
  2. data/Gemfile +6 -0
  3. data/History.txt +5 -0
  4. data/License.txt +30 -0
  5. data/Manifest.txt +217 -0
  6. data/README.rdoc +161 -0
  7. data/Rakefile +52 -0
  8. data/examples/alpha_blend.rb +21 -0
  9. data/examples/box.png +0 -0
  10. data/examples/box_in_scene.png +0 -0
  11. data/examples/contours/bitmap-contours-with-labels.png +0 -0
  12. data/examples/contours/bitmap-contours.png +0 -0
  13. data/examples/contours/bounding-box-detect-canny.rb +62 -0
  14. data/examples/contours/contour_retrieval_modes.rb +139 -0
  15. data/examples/contours/rotated-boxes.jpg +0 -0
  16. data/examples/convexhull.rb +47 -0
  17. data/examples/face_detect.rb +20 -0
  18. data/examples/find_obj.rb +169 -0
  19. data/examples/houghcircle.rb +22 -0
  20. data/examples/inpaint.png +0 -0
  21. data/examples/inpaint.rb +57 -0
  22. data/examples/lenna-rotated.jpg +0 -0
  23. data/examples/lenna.jpg +0 -0
  24. data/examples/match_kdtree.rb +88 -0
  25. data/examples/paint.rb +70 -0
  26. data/examples/snake.rb +43 -0
  27. data/examples/stuff.jpg +0 -0
  28. data/examples/tiffany.jpg +0 -0
  29. data/ext/opencv/curve.cpp +112 -0
  30. data/ext/opencv/curve.h +34 -0
  31. data/ext/opencv/cvavgcomp.cpp +67 -0
  32. data/ext/opencv/cvavgcomp.h +39 -0
  33. data/ext/opencv/cvbox2d.cpp +197 -0
  34. data/ext/opencv/cvbox2d.h +61 -0
  35. data/ext/opencv/cvcapture.cpp +499 -0
  36. data/ext/opencv/cvcapture.h +72 -0
  37. data/ext/opencv/cvchain.cpp +230 -0
  38. data/ext/opencv/cvchain.h +46 -0
  39. data/ext/opencv/cvcircle32f.cpp +116 -0
  40. data/ext/opencv/cvcircle32f.h +52 -0
  41. data/ext/opencv/cvcondensation.cpp +282 -0
  42. data/ext/opencv/cvcondensation.h +49 -0
  43. data/ext/opencv/cvconnectedcomp.cpp +143 -0
  44. data/ext/opencv/cvconnectedcomp.h +49 -0
  45. data/ext/opencv/cvcontour.cpp +297 -0
  46. data/ext/opencv/cvcontour.h +48 -0
  47. data/ext/opencv/cvcontourtree.cpp +91 -0
  48. data/ext/opencv/cvcontourtree.h +41 -0
  49. data/ext/opencv/cvconvexitydefect.cpp +103 -0
  50. data/ext/opencv/cvconvexitydefect.h +42 -0
  51. data/ext/opencv/cverror.cpp +159 -0
  52. data/ext/opencv/cverror.h +28 -0
  53. data/ext/opencv/cvfeaturetree.cpp +125 -0
  54. data/ext/opencv/cvfeaturetree.h +55 -0
  55. data/ext/opencv/cvfont.cpp +208 -0
  56. data/ext/opencv/cvfont.h +64 -0
  57. data/ext/opencv/cvhaarclassifiercascade.cpp +168 -0
  58. data/ext/opencv/cvhaarclassifiercascade.h +39 -0
  59. data/ext/opencv/cvhistogram.cpp +546 -0
  60. data/ext/opencv/cvhistogram.h +73 -0
  61. data/ext/opencv/cvhumoments.cpp +139 -0
  62. data/ext/opencv/cvhumoments.h +51 -0
  63. data/ext/opencv/cvline.cpp +154 -0
  64. data/ext/opencv/cvline.h +54 -0
  65. data/ext/opencv/cvmat.cpp +5627 -0
  66. data/ext/opencv/cvmat.h +280 -0
  67. data/ext/opencv/cvmatnd.cpp +44 -0
  68. data/ext/opencv/cvmatnd.h +28 -0
  69. data/ext/opencv/cvmemstorage.cpp +68 -0
  70. data/ext/opencv/cvmemstorage.h +53 -0
  71. data/ext/opencv/cvmoments.cpp +287 -0
  72. data/ext/opencv/cvmoments.h +75 -0
  73. data/ext/opencv/cvpoint.cpp +228 -0
  74. data/ext/opencv/cvpoint.h +64 -0
  75. data/ext/opencv/cvpoint2d32f.cpp +211 -0
  76. data/ext/opencv/cvpoint2d32f.h +63 -0
  77. data/ext/opencv/cvpoint3d32f.cpp +246 -0
  78. data/ext/opencv/cvpoint3d32f.h +66 -0
  79. data/ext/opencv/cvrect.cpp +333 -0
  80. data/ext/opencv/cvrect.h +79 -0
  81. data/ext/opencv/cvscalar.cpp +236 -0
  82. data/ext/opencv/cvscalar.h +71 -0
  83. data/ext/opencv/cvseq.cpp +599 -0
  84. data/ext/opencv/cvseq.h +72 -0
  85. data/ext/opencv/cvsize.cpp +221 -0
  86. data/ext/opencv/cvsize.h +65 -0
  87. data/ext/opencv/cvsize2d32f.cpp +209 -0
  88. data/ext/opencv/cvsize2d32f.h +64 -0
  89. data/ext/opencv/cvslice.cpp +120 -0
  90. data/ext/opencv/cvslice.h +61 -0
  91. data/ext/opencv/cvsparsemat.cpp +44 -0
  92. data/ext/opencv/cvsparsemat.h +28 -0
  93. data/ext/opencv/cvsurfparams.cpp +199 -0
  94. data/ext/opencv/cvsurfparams.h +58 -0
  95. data/ext/opencv/cvsurfpoint.cpp +223 -0
  96. data/ext/opencv/cvsurfpoint.h +52 -0
  97. data/ext/opencv/cvtermcriteria.cpp +192 -0
  98. data/ext/opencv/cvtermcriteria.h +71 -0
  99. data/ext/opencv/cvtwopoints.cpp +116 -0
  100. data/ext/opencv/cvtwopoints.h +51 -0
  101. data/ext/opencv/cvutils.cpp +194 -0
  102. data/ext/opencv/cvutils.h +29 -0
  103. data/ext/opencv/cvvideowriter.cpp +137 -0
  104. data/ext/opencv/cvvideowriter.h +43 -0
  105. data/ext/opencv/gui.cpp +68 -0
  106. data/ext/opencv/gui.h +30 -0
  107. data/ext/opencv/iplconvkernel.cpp +192 -0
  108. data/ext/opencv/iplconvkernel.h +71 -0
  109. data/ext/opencv/iplimage.cpp +576 -0
  110. data/ext/opencv/iplimage.h +70 -0
  111. data/ext/opencv/lib/opencv.rb +3 -0
  112. data/ext/opencv/lib/opencv/psyched_yaml.rb +22 -0
  113. data/ext/opencv/lib/opencv/version.rb +3 -0
  114. data/ext/opencv/mouseevent.cpp +181 -0
  115. data/ext/opencv/mouseevent.h +56 -0
  116. data/ext/opencv/opencv.cpp +710 -0
  117. data/ext/opencv/opencv.h +400 -0
  118. data/ext/opencv/pointset.cpp +284 -0
  119. data/ext/opencv/pointset.h +69 -0
  120. data/ext/opencv/trackbar.cpp +121 -0
  121. data/ext/opencv/trackbar.h +69 -0
  122. data/ext/opencv/window.cpp +357 -0
  123. data/ext/opencv/window.h +66 -0
  124. data/extconf.rb +65 -0
  125. data/images/CvMat_sobel.png +0 -0
  126. data/images/CvMat_sub_rect.png +0 -0
  127. data/images/CvSeq_relationmap.png +0 -0
  128. data/images/face_detect_from_lena.jpg +0 -0
  129. data/test/helper.rb +146 -0
  130. data/test/runner.rb +30 -0
  131. data/test/samples/airplane.jpg +0 -0
  132. data/test/samples/baboon.jpg +0 -0
  133. data/test/samples/baboon200.jpg +0 -0
  134. data/test/samples/baboon200_rotated.jpg +0 -0
  135. data/test/samples/blank0.jpg +0 -0
  136. data/test/samples/blank1.jpg +0 -0
  137. data/test/samples/blank2.jpg +0 -0
  138. data/test/samples/blank3.jpg +0 -0
  139. data/test/samples/blank4.jpg +0 -0
  140. data/test/samples/blank5.jpg +0 -0
  141. data/test/samples/blank6.jpg +0 -0
  142. data/test/samples/blank7.jpg +0 -0
  143. data/test/samples/blank8.jpg +0 -0
  144. data/test/samples/blank9.jpg +0 -0
  145. data/test/samples/cat.jpg +0 -0
  146. data/test/samples/contours.jpg +0 -0
  147. data/test/samples/fruits.jpg +0 -0
  148. data/test/samples/haarcascade_frontalface_alt.xml.gz +0 -0
  149. data/test/samples/inpaint-mask.bmp +0 -0
  150. data/test/samples/lena-256x256.jpg +0 -0
  151. data/test/samples/lena-32x32.jpg +0 -0
  152. data/test/samples/lena-eyes.jpg +0 -0
  153. data/test/samples/lena-inpaint.jpg +0 -0
  154. data/test/samples/lena.jpg +0 -0
  155. data/test/samples/lines.jpg +0 -0
  156. data/test/samples/messy0.jpg +0 -0
  157. data/test/samples/messy1.jpg +0 -0
  158. data/test/samples/movie_sample.avi +0 -0
  159. data/test/samples/one_way_train_0000.jpg +0 -0
  160. data/test/samples/one_way_train_0001.jpg +0 -0
  161. data/test/samples/partially_blank0.jpg +0 -0
  162. data/test/samples/partially_blank1.jpg +0 -0
  163. data/test/samples/smooth0.jpg +0 -0
  164. data/test/samples/smooth1.jpg +0 -0
  165. data/test/samples/smooth2.jpg +0 -0
  166. data/test/samples/smooth3.jpg +0 -0
  167. data/test/samples/smooth4.jpg +0 -0
  168. data/test/samples/smooth5.jpg +0 -0
  169. data/test/samples/smooth6.jpg +0 -0
  170. data/test/samples/str-cv-rotated.jpg +0 -0
  171. data/test/samples/str-cv.jpg +0 -0
  172. data/test/samples/str-ov.jpg +0 -0
  173. data/test/samples/stuff.jpg +0 -0
  174. data/test/test_curve.rb +43 -0
  175. data/test/test_cvavgcomp.rb +24 -0
  176. data/test/test_cvbox2d.rb +76 -0
  177. data/test/test_cvcapture.rb +183 -0
  178. data/test/test_cvchain.rb +108 -0
  179. data/test/test_cvcircle32f.rb +41 -0
  180. data/test/test_cvconnectedcomp.rb +61 -0
  181. data/test/test_cvcontour.rb +150 -0
  182. data/test/test_cvcontourtree.rb +43 -0
  183. data/test/test_cverror.rb +50 -0
  184. data/test/test_cvfeaturetree.rb +65 -0
  185. data/test/test_cvfont.rb +58 -0
  186. data/test/test_cvhaarclassifiercascade.rb +63 -0
  187. data/test/test_cvhistogram.rb +271 -0
  188. data/test/test_cvhumoments.rb +83 -0
  189. data/test/test_cvline.rb +50 -0
  190. data/test/test_cvmat.rb +2752 -0
  191. data/test/test_cvmat_drawing.rb +318 -0
  192. data/test/test_cvmat_dxt.rb +147 -0
  193. data/test/test_cvmat_imageprocessing.rb +1943 -0
  194. data/test/test_cvmoments.rb +180 -0
  195. data/test/test_cvpoint.rb +75 -0
  196. data/test/test_cvpoint2d32f.rb +75 -0
  197. data/test/test_cvpoint3d32f.rb +93 -0
  198. data/test/test_cvrect.rb +144 -0
  199. data/test/test_cvscalar.rb +113 -0
  200. data/test/test_cvseq.rb +295 -0
  201. data/test/test_cvsize.rb +75 -0
  202. data/test/test_cvsize2d32f.rb +75 -0
  203. data/test/test_cvslice.rb +31 -0
  204. data/test/test_cvsurfparams.rb +57 -0
  205. data/test/test_cvsurfpoint.rb +66 -0
  206. data/test/test_cvtermcriteria.rb +56 -0
  207. data/test/test_cvtwopoints.rb +40 -0
  208. data/test/test_cvvideowriter.rb +58 -0
  209. data/test/test_iplconvkernel.rb +54 -0
  210. data/test/test_iplimage.rb +156 -0
  211. data/test/test_mouseevent.rb +17 -0
  212. data/test/test_opencv.rb +340 -0
  213. data/test/test_pointset.rb +130 -0
  214. data/test/test_preliminary.rb +130 -0
  215. data/test/test_trackbar.rb +47 -0
  216. data/test/test_window.rb +115 -0
  217. metadata +399 -0
@@ -0,0 +1,71 @@
1
+ /************************************************************
2
+
3
+ iplconvkernel.h -
4
+
5
+ $Author: lsxi $
6
+
7
+ Copyright (C) 2005-2006 Masakazu Yonekura
8
+
9
+ ************************************************************/
10
+ #ifndef RUBY_OPENCV_IPLCONVKERNEL_H
11
+ #define RUBY_OPENCV_IPLCONVKERNEL_H
12
+
13
+ #include "opencv.h"
14
+
15
+ #define __NAMESPACE_BEGIN_IPLCONVKERNEL namespace cIplConvKernel {
16
+ #define __NAMESPACE_END_IPLCONVKERNEL }
17
+
18
+ __NAMESPACE_BEGIN_OPENCV
19
+ __NAMESPACE_BEGIN_IPLCONVKERNEL
20
+
21
+ VALUE rb_class();
22
+ VALUE rb_allocate(VALUE klass);
23
+
24
+ void define_ruby_class();
25
+ VALUE rb_initialize(int argc, VALUE *argv, VALUE self);
26
+ VALUE rb_size(VALUE self);
27
+ VALUE rb_cols(VALUE self);
28
+ VALUE rb_rows(VALUE self);
29
+ VALUE rb_anchor(VALUE self);
30
+ VALUE rb_anchor_x(VALUE self);
31
+ VALUE rb_anchor_y(VALUE self);
32
+
33
+ __NAMESPACE_END_IPLCONVKERNEL
34
+
35
+ inline IplConvKernel*
36
+ IPLCONVKERNEL(VALUE object)
37
+ {
38
+ IplConvKernel *ptr;
39
+ Data_Get_Struct(object, IplConvKernel, ptr);
40
+ return ptr;
41
+ }
42
+
43
+ inline IplConvKernel*
44
+ IPLCONVKERNEL_WITH_CHECK(VALUE object)
45
+ {
46
+ if (!rb_obj_is_kind_of(object, cIplConvKernel::rb_class()))
47
+ raise_typeerror(object, cIplConvKernel::rb_class());
48
+ return IPLCONVKERNEL(object);
49
+ }
50
+
51
+ /*
52
+ inline IplConvKernel*
53
+ IPLCONVKERNEL(VALUE object)
54
+ {
55
+ IplConvKernel *ptr;
56
+ if (NIL_P(object))
57
+ return NULL;
58
+ else if (rb_obj_is_kind_of(object, cIplConvKernel::rb_class())) {
59
+ Data_Get_Struct(object, IplConvKernel, ptr);
60
+ return ptr;
61
+ }
62
+ else {
63
+ rb_warn("invalid kernel. use default kernel (3x3 rectangle).");
64
+ return NULL;
65
+ }
66
+ }
67
+ */
68
+
69
+ __NAMESPACE_END_OPENCV
70
+
71
+ #endif // RUBY_OPENCV_IPLCONVKERNEL_H
@@ -0,0 +1,576 @@
1
+ /************************************************************
2
+
3
+ iplimage.cpp -
4
+
5
+ $Author: lsxi $
6
+
7
+ Copyright (C) 2005-2006 Masakazu Yonekura
8
+
9
+ ************************************************************/
10
+ #include "iplimage.h"
11
+ /*
12
+ * Document-class: OpenCV::IplImage
13
+ *
14
+ * IPL(Intel Image Processing Library) Image class.
15
+ *
16
+ * IplImage is subclass of CvMat. IplImage support ROI(region of interest) and COI(color of interest).
17
+ * Most of CvMat method support ROI, and some of CvMat method support COI.
18
+ *
19
+ * =What is ROI?
20
+ * region of interest.
21
+ *
22
+ * =What is COI?
23
+ * color of interest.
24
+ */
25
+ __NAMESPACE_BEGIN_OPENCV
26
+ __NAMESPACE_BEGIN_IPLIMAGE
27
+
28
+ VALUE rb_klass;
29
+
30
+ VALUE
31
+ rb_class()
32
+ {
33
+ return rb_klass;
34
+ }
35
+
36
+ void
37
+ define_ruby_class()
38
+ {
39
+ if (rb_klass)
40
+ return;
41
+ /*
42
+ * opencv = rb_define_module("OpenCV");
43
+ * cvmat = rb_define_class_under(opencv, "CvMat", rb_cObject);
44
+ *
45
+ * note: this comment is used by rdoc.
46
+ */
47
+ VALUE opencv = rb_module_opencv();
48
+ VALUE cvmat = cCvMat::rb_class();
49
+ rb_klass = rb_define_class_under(opencv, "IplImage", cvmat);
50
+ rb_define_alloc_func(rb_klass, rb_allocate);
51
+ rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load_image), -1);
52
+ rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
53
+ rb_define_method(rb_klass, "get_roi", RUBY_METHOD_FUNC(rb_get_roi), 0);
54
+ rb_define_alias(rb_klass, "roi", "get_roi");
55
+ rb_define_method(rb_klass, "set_roi", RUBY_METHOD_FUNC(rb_set_roi), 1);
56
+ rb_define_alias(rb_klass, "roi=", "set_roi");
57
+ rb_define_method(rb_klass, "reset_roi", RUBY_METHOD_FUNC(rb_reset_roi), 0);
58
+ rb_define_method(rb_klass, "get_coi", RUBY_METHOD_FUNC(rb_get_coi), 0);
59
+ rb_define_alias(rb_klass, "coi", "get_coi");
60
+ rb_define_method(rb_klass, "set_coi", RUBY_METHOD_FUNC(rb_set_coi), 1);
61
+ rb_define_alias(rb_klass, "coi=", "set_coi");
62
+ rb_define_method(rb_klass, "reset_coi", RUBY_METHOD_FUNC(rb_reset_coi), 0);
63
+
64
+ rb_define_method(rb_klass, "smoothness", RUBY_METHOD_FUNC(rb_smoothness), -1);
65
+ }
66
+
67
+ VALUE
68
+ rb_allocate(VALUE klass)
69
+ {
70
+ return OPENCV_OBJECT(rb_klass, 0);
71
+ }
72
+
73
+ /*
74
+ * call-seq:
75
+ * new(<i>width, height[, depth = CV_8U][, channel = 3]</i>)
76
+ *
77
+ * Create width * height image. Each element-value set 0.
78
+ *
79
+ * Each element possigle range is set by <i>depth</i>. Default is unsigned 8bit.
80
+ *
81
+ * Number of channel is set by <i>channel</i>. <i>channel</i> should be 1..4.
82
+ *
83
+ * note: width = col, height = row, on CvMat. It is noted not to make a mistake
84
+ * because the order of argument is differenct to CvMat.
85
+ */
86
+ VALUE
87
+ rb_initialize(int argc, VALUE *argv, VALUE self)
88
+ {
89
+ VALUE width, height, depth, channel;
90
+ rb_scan_args(argc, argv, "22", &width, &height, &depth, &channel);
91
+ int _depth = CVMETHOD("DEPTH", depth, CV_8U);
92
+ int _channel = argc < 4 ? 3 : NUM2INT(channel);
93
+ DATA_PTR(self) = rb_cvCreateImage(cvSize(NUM2INT(width), NUM2INT(height)), cvIplDepth(_depth), _channel);
94
+ return self;
95
+ }
96
+
97
+ /*
98
+ * call-seq:
99
+ * IplImage::load(<i>filename[,iscolor = CV_LOAD_IMAGE_COLOR]</i>)
100
+ *
101
+ * Load an image from file.
102
+ * iscolor = CV_LOAD_IMAGE_COLOR, the loaded image is forced to be a 3-channel color image
103
+ * iscolor = CV_LOAD_IMAGE_GRAYSCALE, the loaded image is forced to be grayscale
104
+ * iscolor = CV_LOAD_IMAGE_UNCHANGED, the loaded image will be loaded as is.
105
+ * Currently the following file format are supported.
106
+ * * Windows bitmaps - BMP,DIB
107
+ * * JPEG files - JPEG,JPG,JPE
108
+ * * Portable Network Graphics - PNG
109
+ * * Portable image format - PBM,PGM,PPM
110
+ * * Sun rasters - SR,RAS
111
+ * * TIFF files - TIFF,TIF
112
+ */
113
+ VALUE
114
+ rb_load_image(int argc, VALUE *argv, VALUE self)
115
+ {
116
+ VALUE filename, iscolor;
117
+ rb_scan_args(argc, argv, "11", &filename, &iscolor);
118
+ Check_Type(filename, T_STRING);
119
+
120
+ int _iscolor;
121
+ if (TYPE(iscolor) == T_NIL) {
122
+ _iscolor = CV_LOAD_IMAGE_COLOR;
123
+ }
124
+ else {
125
+ Check_Type(iscolor, T_FIXNUM);
126
+ _iscolor = FIX2INT(iscolor);
127
+ }
128
+
129
+ IplImage *image;
130
+ if ((image = cvLoadImage(StringValueCStr(filename), _iscolor)) == NULL) {
131
+ rb_raise(rb_eStandardError, "file does not exist or invalid format image.");
132
+ }
133
+ return OPENCV_OBJECT(rb_klass, image);
134
+ }
135
+
136
+ /*
137
+ * Get ROI as CvRect.
138
+ */
139
+ VALUE
140
+ rb_get_roi(VALUE self)
141
+ {
142
+ CvRect rect;
143
+ try {
144
+ rect = cvGetImageROI(IPLIMAGE(self));
145
+ }
146
+ catch (cv::Exception& e) {
147
+ raise_cverror(e);
148
+ }
149
+ return cCvRect::new_object(rect);
150
+ }
151
+
152
+ /*
153
+ * call-seq:
154
+ * set_roi(<i>rect</i>)
155
+ * set_roi(<i>rect</i>){|image| ...}
156
+ *
157
+ * Set ROI. <i>rect</i> should be CvRect or compatible object.
158
+ * Return self.
159
+ */
160
+ VALUE
161
+ rb_set_roi(VALUE self, VALUE roi)
162
+ {
163
+ VALUE block = rb_block_given_p() ? rb_block_proc() : 0;
164
+ try {
165
+ if (block) {
166
+ CvRect prev_roi = cvGetImageROI(IPLIMAGE(self));
167
+ cvSetImageROI(IPLIMAGE(self), VALUE_TO_CVRECT(roi));
168
+ rb_yield_values(1, self);
169
+ cvSetImageROI(IPLIMAGE(self), prev_roi);
170
+ }
171
+ else {
172
+ cvSetImageROI(IPLIMAGE(self), VALUE_TO_CVRECT(roi));
173
+ }
174
+ }
175
+ catch (cv::Exception& e) {
176
+ raise_cverror(e);
177
+ }
178
+ return self;
179
+ }
180
+
181
+
182
+ /*
183
+ * Reset ROI setting. Same as IplImage#roi = nil. Return self.
184
+ */
185
+ VALUE
186
+ rb_reset_roi(VALUE self)
187
+ {
188
+ try {
189
+ cvResetImageROI(IPLIMAGE(self));
190
+ }
191
+ catch (cv::Exception& e) {
192
+ raise_cverror(e);
193
+ }
194
+ return self;
195
+ }
196
+
197
+ /*
198
+ * Return COI as Fixnum.
199
+ */
200
+ VALUE
201
+ rb_get_coi(VALUE self)
202
+ {
203
+ int coi = 0;
204
+ try {
205
+ coi = cvGetImageCOI(IPLIMAGE(self));
206
+ }
207
+ catch (cv::Exception& e) {
208
+ raise_cverror(e);
209
+ }
210
+ return INT2FIX(coi);
211
+ }
212
+
213
+ /*
214
+ * call-seq:
215
+ * set_coi(<i>coi</i>)
216
+ * set_coi(<i>coi</i>){|image| ...}
217
+ *
218
+ * Set COI. <i>coi</i> should be Fixnum.
219
+ * Return self.
220
+ */
221
+ VALUE
222
+ rb_set_coi(VALUE self, VALUE coi)
223
+ {
224
+ VALUE block = rb_block_given_p() ? rb_block_proc() : 0;
225
+ try {
226
+ if (block) {
227
+ int prev_coi = cvGetImageCOI(IPLIMAGE(self));
228
+ cvSetImageCOI(IPLIMAGE(self), NUM2INT(coi));
229
+ rb_yield_values(1, self);
230
+ cvSetImageCOI(IPLIMAGE(self), prev_coi);
231
+ }
232
+ else {
233
+ cvSetImageCOI(IPLIMAGE(self), NUM2INT(coi));
234
+ }
235
+ }
236
+ catch (cv::Exception& e) {
237
+ raise_cverror(e);
238
+ }
239
+ return self;
240
+ }
241
+
242
+ /*
243
+ * Reset COI setting. Same as IplImage#coi = 0. Return self.
244
+ */
245
+ VALUE
246
+ rb_reset_coi(VALUE self)
247
+ {
248
+ try {
249
+ cvSetImageCOI(IPLIMAGE(self), 0);
250
+ }
251
+ catch (cv::Exception& e) {
252
+ raise_cverror(e);
253
+ }
254
+ return self;
255
+ }
256
+
257
+ /*
258
+ * call-seq:
259
+ * IplImage.smoothness(<i>lowFreqRatio, blankDensity, messyDensity, highFreqRatio</i>) -> [ symbol, float, float ]
260
+ *
261
+ * Determines if the image's smoothness is either, :smooth, :messy, or :blank.
262
+ *
263
+ * Original Author: yuhanz@gmail.com
264
+ */
265
+ VALUE
266
+ rb_smoothness(int argc, VALUE *argv, VALUE self)
267
+ {
268
+ VALUE lowFreqRatio, blankDensity, messyDensity, highFreqRatio;
269
+ rb_scan_args(argc, argv, "04", &lowFreqRatio, &blankDensity, &messyDensity, &highFreqRatio);
270
+
271
+ double f_lowFreqRatio, f_blankDensity, f_messyDensity, f_highFreqRatio;
272
+ double outLowDensity, outHighDensity;
273
+ if (TYPE(lowFreqRatio) == T_NIL) {
274
+ f_lowFreqRatio = 10 / 128.0f;
275
+ }
276
+ else {
277
+ Check_Type(lowFreqRatio, T_FLOAT);
278
+ f_lowFreqRatio = NUM2DBL(lowFreqRatio);
279
+ }
280
+ if (TYPE(blankDensity) == T_NIL) {
281
+ f_blankDensity = 1.2f;
282
+ }
283
+ else {
284
+ Check_Type(blankDensity, T_FLOAT);
285
+ f_blankDensity = NUM2DBL(blankDensity);
286
+ }
287
+ if (TYPE(messyDensity) == T_NIL) {
288
+ f_messyDensity = 0.151f;
289
+ }
290
+ else {
291
+ Check_Type(messyDensity, T_FLOAT);
292
+ f_messyDensity = NUM2DBL(messyDensity);
293
+ }
294
+ if (TYPE(highFreqRatio) == T_NIL) {
295
+ f_highFreqRatio = 5 / 128.0f;
296
+ }
297
+ else {
298
+ Check_Type(highFreqRatio, T_FLOAT);
299
+ f_highFreqRatio = NUM2DBL(highFreqRatio);
300
+ }
301
+
302
+ IplImage *pFourierImage;
303
+ IplImage *p64DepthImage;
304
+
305
+ // the image is required to be in depth of 64
306
+ if (IPLIMAGE(self)->depth == 64) {
307
+ p64DepthImage = NULL;
308
+ pFourierImage = create_fourier_image(IPLIMAGE(self));
309
+ }
310
+ else {
311
+ p64DepthImage = rb_cvCreateImage(cvGetSize(IPLIMAGE(self)), IPL_DEPTH_64F, 1);
312
+ cvConvertScale(CVARR(self), p64DepthImage, 1.0, 0.0);
313
+ pFourierImage = create_fourier_image(p64DepthImage);
314
+ }
315
+
316
+ Smoothness result = compute_smoothness(pFourierImage, f_lowFreqRatio, f_blankDensity, f_messyDensity,
317
+ f_highFreqRatio, outLowDensity, outHighDensity);
318
+
319
+ cvReleaseImage(&pFourierImage);
320
+ if (p64DepthImage != NULL)
321
+ cvReleaseImage(&p64DepthImage);
322
+
323
+ switch(result) {
324
+ case SMOOTH:
325
+ return rb_ary_new3(3, ID2SYM(rb_intern("smooth")), rb_float_new(outLowDensity), rb_float_new(outHighDensity));
326
+ case MESSY:
327
+ return rb_ary_new3(3, ID2SYM(rb_intern("messy")), rb_float_new(outLowDensity), rb_float_new(outHighDensity));
328
+ case BLANK:
329
+ return rb_ary_new3(3, ID2SYM(rb_intern("blank")), rb_float_new(outLowDensity), rb_float_new(outHighDensity));
330
+ default:
331
+ return rb_ary_new3(3, NULL, rb_float_new(outLowDensity), rb_float_new(outHighDensity));
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Note: if lowDensity < blankDensityThreshold -> blank;
337
+ * else if highDensity > messyDensityThreshold -> messy;
338
+ * else -> good;
339
+ */
340
+ Smoothness
341
+ compute_smoothness(const IplImage *pFourierImage, const double lowFreqRatio, const double blankDensity,
342
+ const double messyDensity, const double highFreqRatio, double &outLowDensity,
343
+ double &outHighDensity)
344
+ {
345
+ int low, high;
346
+ IplImage *filteredFourierImage;
347
+ int totalIntensity;
348
+ double sum, den, totalArea;
349
+ CvScalar scalar;
350
+
351
+ if (!(pFourierImage->nChannels == 1 && pFourierImage->depth == 64) ) {
352
+ cvError(CV_StsUnmatchedSizes, "compute_smoothness", "input image must contain only 1 channel and a depth of 64",
353
+ __FILE__, __LINE__ );
354
+ }
355
+
356
+ high_pass_range(pFourierImage, lowFreqRatio, low, high );
357
+ totalArea = M_PI * (high * high - low * low);
358
+
359
+ filteredFourierImage = create_frequency_filtered_image(pFourierImage, low, high);
360
+ scalar = cvSum(filteredFourierImage);
361
+ totalIntensity = (int)scalar.val[0];
362
+ cvReleaseImage(&filteredFourierImage);
363
+ outLowDensity = den = totalIntensity / totalArea;
364
+
365
+ if (den <= blankDensity) {
366
+ return BLANK;
367
+ }
368
+
369
+ low = (int)(high * (1.0 - highFreqRatio));
370
+
371
+ filteredFourierImage = create_frequency_filtered_image(pFourierImage, low, high);
372
+ scalar = cvSum(filteredFourierImage);
373
+ totalIntensity = (int)scalar.val[0];
374
+ cvReleaseImage(&filteredFourierImage);
375
+ outHighDensity = den = totalIntensity / totalArea;
376
+
377
+ if (den >= messyDensity) {
378
+ return MESSY;
379
+ }
380
+
381
+ return SMOOTH;
382
+ }
383
+
384
+ // Rearrange the quadrants of Fourier image so that the origin is at
385
+ // the image center
386
+ // src & dst arrays of equal size & type
387
+ void
388
+ cvShiftDFT(CvArr *src_arr, CvArr *dst_arr )
389
+ {
390
+ CvMat *tmp = NULL;
391
+ CvMat q1stub, q2stub;
392
+ CvMat q3stub, q4stub;
393
+ CvMat d1stub, d2stub;
394
+ CvMat d3stub, d4stub;
395
+ CvMat *q1, *q2, *q3, *q4;
396
+ CvMat *d1, *d2, *d3, *d4;
397
+
398
+ CvSize size = cvGetSize(src_arr);
399
+ CvSize dst_size = cvGetSize(dst_arr);
400
+ int cx, cy;
401
+
402
+ if (dst_size.width != size.width ||
403
+ dst_size.height != size.height) {
404
+ cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes",
405
+ __FILE__, __LINE__ );
406
+ }
407
+
408
+ if (src_arr == dst_arr) {
409
+ tmp = rb_cvCreateMat(size.height / 2, size.width / 2, cvGetElemType(src_arr));
410
+ }
411
+
412
+ cx = size.width / 2;
413
+ cy = size.height / 2; // image center
414
+
415
+ q1 = cvGetSubRect(src_arr, &q1stub, cvRect(0,0,cx, cy));
416
+ q2 = cvGetSubRect(src_arr, &q2stub, cvRect(cx,0,cx,cy));
417
+ q3 = cvGetSubRect(src_arr, &q3stub, cvRect(cx,cy,cx,cy));
418
+ q4 = cvGetSubRect(src_arr, &q4stub, cvRect(0,cy,cx,cy));
419
+ d1 = cvGetSubRect(src_arr, &d1stub, cvRect(0,0,cx,cy));
420
+ d2 = cvGetSubRect(src_arr, &d2stub, cvRect(cx,0,cx,cy));
421
+ d3 = cvGetSubRect(src_arr, &d3stub, cvRect(cx,cy,cx,cy));
422
+ d4 = cvGetSubRect(src_arr, &d4stub, cvRect(0,cy,cx,cy));
423
+
424
+ if (src_arr != dst_arr) {
425
+ if (!CV_ARE_TYPES_EQ(q1, d1)) {
426
+ cvError(CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format",
427
+ __FILE__, __LINE__ );
428
+ }
429
+ cvCopy(q3, d1, 0);
430
+ cvCopy(q4, d2, 0);
431
+ cvCopy(q1, d3, 0);
432
+ cvCopy(q2, d4, 0);
433
+ }
434
+ else {
435
+ cvCopy(q3, tmp, 0);
436
+ cvCopy(q1, q3, 0);
437
+ cvCopy(tmp, q1, 0);
438
+ cvCopy(q4, tmp, 0);
439
+ cvCopy(q2, q4, 0);
440
+ cvCopy(tmp, q2, 0);
441
+ }
442
+
443
+ if (tmp != NULL) {
444
+ cvReleaseMat(&tmp);
445
+ }
446
+ }
447
+
448
+ IplImage*
449
+ create_fourier_image(const IplImage *im)
450
+ {
451
+ IplImage *realInput;
452
+ IplImage *imaginaryInput;
453
+ IplImage *complexInput;
454
+ int dft_M, dft_N;
455
+ CvMat *dft_A, tmp;
456
+ IplImage *image_Re;
457
+ IplImage *image_Im;
458
+
459
+ realInput = rb_cvCreateImage(cvGetSize(im), IPL_DEPTH_64F, 1);
460
+ imaginaryInput = rb_cvCreateImage(cvGetSize(im), IPL_DEPTH_64F, 1);
461
+ complexInput = rb_cvCreateImage(cvGetSize(im), IPL_DEPTH_64F, 2);
462
+
463
+ cvScale(im, realInput, 1.0, 0.0);
464
+ cvZero(imaginaryInput);
465
+ cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput);
466
+
467
+ dft_M = cvGetOptimalDFTSize(im->height - 1);
468
+ dft_N = cvGetOptimalDFTSize(im->width - 1);
469
+
470
+ dft_A = rb_cvCreateMat(dft_M, dft_N, CV_64FC2);
471
+ image_Re = rb_cvCreateImage(cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
472
+ image_Im = rb_cvCreateImage(cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
473
+
474
+ // copy A to dft_A and pad dft_A with zeros
475
+ cvGetSubRect(dft_A, &tmp, cvRect(0,0, im->width, im->height));
476
+ cvCopy(complexInput, &tmp, NULL);
477
+ if (dft_A->cols > im->width) {
478
+ cvGetSubRect(dft_A, &tmp, cvRect(im->width,0, dft_A->cols - im->width, im->height));
479
+ cvZero(&tmp);
480
+ }
481
+
482
+ // no need to pad bottom part of dft_A with zeros because of
483
+ // use nonzero_rows parameter in cvDFT() call below
484
+
485
+ cvDFT(dft_A, dft_A, CV_DXT_FORWARD, complexInput->height);
486
+
487
+ // Split Fourier in real and imaginary parts
488
+ cvSplit(dft_A, image_Re, image_Im, 0, 0);
489
+
490
+ // Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
491
+ cvPow(image_Re, image_Re, 2.0);
492
+ cvPow(image_Im, image_Im, 2.0);
493
+ cvAdd(image_Re, image_Im, image_Re, NULL);
494
+ cvPow(image_Re, image_Re, 0.5);
495
+
496
+ // Compute log(1 + Mag)
497
+ cvAddS(image_Re, cvScalarAll(1.0), image_Re, NULL); // 1 + Mag
498
+ cvLog(image_Re, image_Re); // log(1 + Mag)
499
+
500
+ // Rearrange the quadrants of Fourier image so that the origin is at
501
+ // the image center
502
+ cvShiftDFT(image_Re, image_Re);
503
+
504
+ cvReleaseImage(&realInput);
505
+ cvReleaseImage(&imaginaryInput);
506
+ cvReleaseImage(&complexInput);
507
+ cvReleaseImage(&image_Im);
508
+
509
+ cvReleaseMat(&dft_A);
510
+
511
+ return image_Re;
512
+ }
513
+
514
+ IplImage*
515
+ create_frequency_filtered_image(const IplImage *pImage, int low, int high)
516
+ {
517
+
518
+ CvPoint2D32f center;
519
+ center.x = (float)(pImage->width / 2);
520
+ center.y = (float)(pImage->height / 2);
521
+ CvBox2D box;
522
+ box.center = center;
523
+
524
+ box.size.width = (float)high;
525
+ box.size.height = (float)high;
526
+
527
+ IplImage *pFilterMask = rb_cvCreateImage(cvGetSize(pImage), IPL_DEPTH_64F, 1);
528
+ IplImage *pFiltered = rb_cvCreateImage(cvGetSize(pImage), IPL_DEPTH_64F, 1);
529
+
530
+ cvZero(pFilterMask);
531
+ cvZero(pFiltered);
532
+
533
+ if (high > 0)
534
+ cvEllipseBox(pFilterMask, box, cvScalar(255, 255, 255, 255), CV_FILLED, 8, 0);
535
+
536
+ box.size.width = (float)low;
537
+ box.size.height = (float)low;
538
+ if (low > 0)
539
+ cvEllipseBox(pFilterMask, box, cvScalar(0, 0, 0, 0), CV_FILLED, 8, 0);
540
+
541
+ cvAnd(pImage, pFilterMask, pFiltered, NULL);
542
+
543
+ cvReleaseImage(&pFilterMask);
544
+
545
+ return pFiltered;
546
+ }
547
+
548
+ void
549
+ high_pass_range(const IplImage *pImage, float lostPercentage, int &outLow, int &outHigh)
550
+ {
551
+ if (lostPercentage > 1.0f) {
552
+ lostPercentage = 1;
553
+ }
554
+ else if (lostPercentage < 0.0f) {
555
+ lostPercentage = 0;
556
+ }
557
+
558
+ outHigh = (int)MIN(pImage->width, pImage->height);
559
+ outLow = (int)(lostPercentage * outHigh);
560
+ }
561
+
562
+
563
+ VALUE
564
+ new_object(int width, int height, int type)
565
+ {
566
+ return OPENCV_OBJECT(rb_klass, rb_cvCreateImage(cvSize(width, height), cvIplDepth(type), CV_MAT_CN(type)));
567
+ }
568
+
569
+ VALUE
570
+ new_object(CvSize size, int type)
571
+ {
572
+ return OPENCV_OBJECT(rb_klass, rb_cvCreateImage(size, cvIplDepth(type), CV_MAT_CN(type)));
573
+ }
574
+
575
+ __NAMESPACE_END_IPLIMAGE
576
+ __NAMESPACE_END_OPENCV