From fcae1a1d44318c4e8b7320850442a2d0372899f0 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Sun, 16 Jan 2011 17:15:56 +0900 Subject: [PATCH] modified CvMat#rect_sub_pix and CvMat#quadrangle_sub_pix, and added some tests --- ext/cvmat.cpp | 309 +++++++++++++++-------------- ext/cvmat.h | 4 +- test/test_cvmat_imageprocessing.rb | 41 +++- 3 files changed, 202 insertions(+), 152 deletions(-) diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp index 99f7f7f..eaef3b3 100644 --- a/ext/cvmat.cpp +++ b/ext/cvmat.cpp @@ -12,7 +12,7 @@ * Document-class: OpenCV::CvMat * * CvMat is basic 2D matrix class in OpenCV. - * + * * C structure is here. * typedef struct CvMat{ * int type; @@ -30,7 +30,7 @@ * union * { * int rows; - * int height; + * int height; * }; * union * { @@ -100,16 +100,16 @@ void define_ruby_class() { if (rb_klass) return; - /* + /* * opencv = rb_define_module("OpenCV"); - * + * * note: this comment is used by rdoc. */ VALUE opencv = rb_module_opencv(); - + rb_klass = rb_define_class_under(opencv, "CvMat", rb_cObject); rb_define_alloc_func(rb_klass, rb_allocate); - + VALUE drawing_option = rb_hash_new(); rb_define_const(rb_klass, "DRAWING_OPTION", drawing_option); rb_hash_aset(drawing_option, ID2SYM(rb_intern("color")), cCvScalar::new_object(cvScalarAll(0))); @@ -147,7 +147,7 @@ void define_ruby_class() rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("block_size")), cCvSize::new_object(cvSize(4, 4))); rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("shift_size")), cCvSize::new_object(cvSize(1, 1))); rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("max_range")), cCvSize::new_object(cvSize(4, 4))); - + VALUE find_fundamental_matrix_option = rb_hash_new(); rb_define_const(rb_klass, "FIND_FUNDAMENTAL_MAT_OPTION", find_fundamental_matrix_option); rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("with_status")), Qfalse); @@ -176,7 +176,7 @@ void define_ruby_class() rb_define_method(rb_klass, "clone", RUBY_METHOD_FUNC(rb_clone), 0); rb_define_method(rb_klass, "copy", RUBY_METHOD_FUNC(rb_copy), -1); - rb_define_method(rb_klass, "to_8u", RUBY_METHOD_FUNC(rb_to_8u), 0); + rb_define_method(rb_klass, "to_8u", RUBY_METHOD_FUNC(rb_to_8u), 0); rb_define_method(rb_klass, "to_8s", RUBY_METHOD_FUNC(rb_to_8s), 0); rb_define_method(rb_klass, "to_16u", RUBY_METHOD_FUNC(rb_to_16u), 0); rb_define_method(rb_klass, "to_16s", RUBY_METHOD_FUNC(rb_to_16s), 0); @@ -185,7 +185,7 @@ void define_ruby_class() rb_define_method(rb_klass, "to_64f", RUBY_METHOD_FUNC(rb_to_64f), 0); rb_define_method(rb_klass, "vector?", RUBY_METHOD_FUNC(rb_vector_q), 0); rb_define_method(rb_klass, "square?", RUBY_METHOD_FUNC(rb_square_q), 0); - + rb_define_method(rb_klass, "to_CvMat", RUBY_METHOD_FUNC(rb_to_CvMat), 0); rb_define_method(rb_klass, "sub_rect", RUBY_METHOD_FUNC(rb_sub_rect), -2); rb_define_alias(rb_klass, "subrect", "sub_rect"); @@ -217,7 +217,7 @@ void define_ruby_class() rb_define_method(rb_klass, "identity!", RUBY_METHOD_FUNC(rb_set_identity_bang), -1); rb_define_method(rb_klass, "range", RUBY_METHOD_FUNC(rb_range), -1); rb_define_method(rb_klass, "range!", RUBY_METHOD_FUNC(rb_range_bang), -1); - + rb_define_method(rb_klass, "reshape", RUBY_METHOD_FUNC(rb_reshape), 1); rb_define_method(rb_klass, "repeat", RUBY_METHOD_FUNC(rb_repeat), 1); rb_define_method(rb_klass, "flip", RUBY_METHOD_FUNC(rb_flip), -1); @@ -285,7 +285,7 @@ void define_ruby_class() rb_define_method(rb_klass, "eigenvv", RUBY_METHOD_FUNC(rb_eigenvv), -1); rb_define_method(rb_klass, "calc_covar_matrix", RUBY_METHOD_FUNC(rb_calc_covar_matrix), -1); rb_define_method(rb_klass, "mahalonobis", RUBY_METHOD_FUNC(rb_mahalonobis), -1); - + /* drawing function */ rb_define_method(rb_klass, "line", RUBY_METHOD_FUNC(rb_line), -1); rb_define_method(rb_klass, "line!", RUBY_METHOD_FUNC(rb_line_bang), -1); @@ -308,7 +308,7 @@ void define_ruby_class() rb_define_method(rb_klass, "dft", RUBY_METHOD_FUNC(rb_dft), -1); rb_define_method(rb_klass, "dct", RUBY_METHOD_FUNC(rb_dct), -1); - + rb_define_method(rb_klass, "sobel", RUBY_METHOD_FUNC(rb_sobel), -1); rb_define_method(rb_klass, "laplace", RUBY_METHOD_FUNC(rb_laplace), -1); rb_define_method(rb_klass, "canny", RUBY_METHOD_FUNC(rb_canny), -1); @@ -320,8 +320,8 @@ void define_ruby_class() rb_define_method(rb_klass, "good_features_to_track", RUBY_METHOD_FUNC(rb_good_features_to_track), -1); rb_define_method(rb_klass, "sample_line", RUBY_METHOD_FUNC(rb_sample_line), 2); - rb_define_method(rb_klass, "rect_sub_pix", RUBY_METHOD_FUNC(rb_rect_sub_pix), 2); - rb_define_method(rb_klass, "quadrangle_sub_pix", RUBY_METHOD_FUNC(rb_quadrangle_sub_pix), 2); + rb_define_method(rb_klass, "rect_sub_pix", RUBY_METHOD_FUNC(rb_rect_sub_pix), -1); + rb_define_method(rb_klass, "quadrangle_sub_pix", RUBY_METHOD_FUNC(rb_quadrangle_sub_pix), -1); rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1); rb_define_method(rb_klass, "warp_affine", RUBY_METHOD_FUNC(rb_warp_affine), -1); rb_define_singleton_method(rb_klass, "rotation", RUBY_METHOD_FUNC(rb_rotation), 3); @@ -330,7 +330,7 @@ void define_ruby_class() //rb_define_alias(rb_klass, "warp_perspective_q_matrix", "get_perspective_transform"); rb_define_method(rb_klass, "remap", RUBY_METHOD_FUNC(rb_remap), -1); //rb_define_method(rb_klass, "log_polar", RUBY_METHOD_FUNC(rb_log_polar), -1); - + rb_define_method(rb_klass, "erode", RUBY_METHOD_FUNC(rb_erode), -1); rb_define_method(rb_klass, "erode!", RUBY_METHOD_FUNC(rb_erode_bang), -1); rb_define_method(rb_klass, "dilate", RUBY_METHOD_FUNC(rb_dilate), -1); @@ -340,7 +340,7 @@ void define_ruby_class() rb_define_method(rb_klass, "morphology_gradient", RUBY_METHOD_FUNC(rb_morphology_gradient), -1); rb_define_method(rb_klass, "morphology_tophat", RUBY_METHOD_FUNC(rb_morphology_tophat), -1); rb_define_method(rb_klass, "morphology_blackhat", RUBY_METHOD_FUNC(rb_morphology_blackhat), -1); - + rb_define_method(rb_klass, "smooth_blur_no_scale", RUBY_METHOD_FUNC(rb_smooth_blur_no_scale), -1); rb_define_method(rb_klass, "smooth_blur", RUBY_METHOD_FUNC(rb_smooth_blur), -1); rb_define_method(rb_klass, "smooth_gaussian", RUBY_METHOD_FUNC(rb_smooth_gaussian), -1); @@ -374,7 +374,7 @@ void define_ruby_class() rb_define_method(rb_klass, "hough_lines_multi_scale", RUBY_METHOD_FUNC(rb_hough_lines_multi_scale), -1); rb_define_method(rb_klass, "hough_circles_gradient", RUBY_METHOD_FUNC(rb_hough_circles_gradient), -1); //rb_define_method(rb_klass, "dist_transform", RUBY_METHOD_FUNC(rb_dist_transform), -1); - + rb_define_method(rb_klass, "inpaint_ns", RUBY_METHOD_FUNC(rb_inpaint_ns), 2); rb_define_method(rb_klass, "inpaint_telea", RUBY_METHOD_FUNC(rb_inpaint_telea), 2); @@ -383,15 +383,15 @@ void define_ruby_class() rb_define_method(rb_klass, "match_shapes_i1", RUBY_METHOD_FUNC(rb_match_shapes_i1), -1); rb_define_method(rb_klass, "match_shapes_i2", RUBY_METHOD_FUNC(rb_match_shapes_i2), -1); rb_define_method(rb_klass, "match_shapes_i3", RUBY_METHOD_FUNC(rb_match_shapes_i3), -1); - + rb_define_method(rb_klass, "mean_shift", RUBY_METHOD_FUNC(rb_mean_shift), 2); rb_define_method(rb_klass, "cam_shift", RUBY_METHOD_FUNC(rb_cam_shift), 2); rb_define_method(rb_klass, "snake_image", RUBY_METHOD_FUNC(rb_snake_image), -1); - + rb_define_method(rb_klass, "optical_flow_hs", RUBY_METHOD_FUNC(rb_optical_flow_hs), -1); rb_define_method(rb_klass, "optical_flow_lk", RUBY_METHOD_FUNC(rb_optical_flow_lk), -1); rb_define_method(rb_klass, "optical_flow_bm", RUBY_METHOD_FUNC(rb_optical_flow_bm), -1); - + rb_define_singleton_method(rb_klass, "find_fundamental_mat_7point", RUBY_METHOD_FUNC(rb_find_fundamental_mat_7point), -1); rb_define_singleton_method(rb_klass, "find_fundamental_mat_8point", RUBY_METHOD_FUNC(rb_find_fundamental_mat_8point), -1); rb_define_singleton_method(rb_klass, "find_fundamental_mat_ransac", RUBY_METHOD_FUNC(rb_find_fundamental_mat_ransac), -1); @@ -407,7 +407,7 @@ rb_allocate(VALUE klass) return OPENCV_OBJECT(klass, 0); } -/* +/* * call-seq: * CvMat.new(row, col[, depth = CV_8U][, channel = 3]) -> cvmat * @@ -442,7 +442,7 @@ rb_initialize(int argc, VALUE *argv, VALUE self) * * JPEG files - JPEG,JPG,JPE * * Portable Network Graphics - PNG * * Portable image format - PBM,PGM,PPM - * * Sun rasters - SR,RAS + * * Sun rasters - SR,RAS * * TIFF files - TIFF,TIF */ VALUE @@ -460,7 +460,7 @@ rb_load_imageM(int argc, VALUE *argv, VALUE self) Check_Type(iscolor, T_FIXNUM); _iscolor = FIX2INT(iscolor); } - + CvMat *mat; if ((mat = cvLoadImageM(StringValueCStr(filename), _iscolor)) == NULL) { rb_raise(rb_eStandardError, "file does not exist or invalid format image."); @@ -469,7 +469,7 @@ rb_load_imageM(int argc, VALUE *argv, VALUE self) } -/* +/* * nodoc */ VALUE @@ -530,7 +530,7 @@ rb_to_s(VALUE self) VALUE rb_has_parent_q(VALUE self) { - return lookup_root_object(CVMAT(self)) ? Qtrue : Qfalse; + return lookup_root_object(CVMAT(self)) ? Qtrue : Qfalse; } /* @@ -550,9 +550,9 @@ rb_parent(VALUE self) * call-seq: * inside?(obj) -> true or false * - * + * */ -VALUE +VALUE rb_inside_q(VALUE self, VALUE object) { if (cCvPoint::rb_compatible_q(cCvPoint::rb_class(), object)) { @@ -563,8 +563,8 @@ rb_inside_q(VALUE self, VALUE object) int width = NUM2INT(rb_funcall(object, rb_intern("width"), 0)); int height = NUM2INT(rb_funcall(object, rb_intern("height"), 0)); return x >= 0 && y >= 0 && x < mat->width && x + width < mat->width && y < mat->height && y + height < mat->height ? Qtrue : Qfalse; - } else { - return x >= 0 && y >= 0 && x < mat->width && y < mat->height ? Qtrue : Qfalse; + } else { + return x >= 0 && y >= 0 && x < mat->width && y < mat->height ? Qtrue : Qfalse; } } rb_raise(rb_eArgError, "argument 1 should have method \"x\", \"y\""); @@ -588,7 +588,7 @@ rb_to_IplConvKernel(VALUE self, VALUE anchor) /* * call-seq: * create_mask -> cvmat(single-channel 8bit unsinged image) - * + * * Create single-channel 8bit unsinged image that filled 0. */ VALUE @@ -598,7 +598,7 @@ rb_create_mask(VALUE self) cvZero(CVARR(self)); return mask; } - + /* * call-seq: * width -> int @@ -610,7 +610,7 @@ rb_width(VALUE self) { return INT2FIX(CVMAT(self)->width); } - + /* * call-seq: * height -> int @@ -642,7 +642,7 @@ rb_depth(VALUE self) * Return number of channel. */ VALUE -rb_channel(VALUE self) +rb_channel(VALUE self) { return INT2FIX(CV_MAT_CN(CVMAT(self)->type)); } @@ -1032,7 +1032,7 @@ rb_row(VALUE self, VALUE args) }else{ CvSlice slice = VALUE_TO_CVSLICE(value); rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRows(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self)); - } + } } return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0); } @@ -1058,7 +1058,7 @@ rb_col(VALUE self, VALUE args) }else{ CvSlice slice = VALUE_TO_CVSLICE(value); rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCols(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self)); - } + } } return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0); } @@ -1113,13 +1113,13 @@ rb_diag(int argc, VALUE *argv, VALUE self) VALUE val; if (rb_scan_args(argc, argv, "01", &val) < 1) { val = INT2FIX(0); - } + } return DEPEND_OBJECT(rb_klass, cvGetDiag(CVARR(self), CVALLOC(CvMat), NUM2INT(val)), self); } /* * call-seq: - * size -> cvsize + * size -> cvsize * * Return size by CvSize */ @@ -1136,7 +1136,7 @@ rb_size(VALUE self) */ /* - * call-seq: + * call-seq: * dims -> array(int, int, ...) * * Return number of array dimensions and their sizes or the size of particular dimension. @@ -1182,7 +1182,7 @@ rb_aref(VALUE self, VALUE args) index[i] = NUM2INT(rb_ary_entry(args, i)); } CvScalar scalar = cvScalarAll(0); - switch(RARRAY_LEN(args)) { + switch(RARRAY_LEN(args)) { case 1: scalar = cvGet1D(CVARR(self), index[0]); break; @@ -1289,7 +1289,7 @@ rb_fill_bang(int argc, VALUE *argv, VALUE self) VALUE rb_save_image(VALUE self, VALUE filename) { - Check_Type(filename, T_STRING); + Check_Type(filename, T_STRING); cvSaveImage(StringValueCStr(filename), CVARR(self)); return self; } @@ -1500,9 +1500,9 @@ rb_split(VALUE self) { int type = CVMAT(self)->type, depth = CV_MAT_DEPTH(type), channel = CV_MAT_CN(type); CvSize size = cvGetSize(CVARR(self)); - CvMat *dest[] = {NULL, NULL, NULL, NULL}; + CvMat *dest[] = {NULL, NULL, NULL, NULL}; for (int i = 0; i < channel; i++) - dest[i] = cvCreateMat(size.height, size.width, CV_MAKETYPE(depth, 1)); + dest[i] = cvCreateMat(size.height, size.width, CV_MAKETYPE(depth, 1)); cvSplit(CVARR(self), dest[0], dest[1], dest[2], dest[3]); VALUE ary = rb_ary_new2(channel); for (int i = 0; i < channel; i++) @@ -1571,7 +1571,7 @@ rb_mix_channels(int argc, VALUE *argv, VALUE self) * rand_shuffle([seed = nil][,iter_factor = 1]) -> cvmat * * Return shuffled matrix - * + * * see rand_shuffle! */ VALUE @@ -1584,10 +1584,10 @@ rb_rand_shuffle(int argc, VALUE *argv, VALUE self) * call-seq: * rand_shuffle!([seed = nil][,iter_factor = 1]) -> cvmat * - * Shuffles the matrix by swapping randomly chosen pairs of the matrix elements on each iteration - * (where each element may contain several components in case of multi-channel arrays). The number of - * iterations (i.e. pairs swapped) is (iter_factor*mat.rows*mat.cols).round, so iter_factor=0 means - * that no shuffling is done, iter_factor=1 means that the function swaps rows(mat)*cols(mat) random + * Shuffles the matrix by swapping randomly chosen pairs of the matrix elements on each iteration + * (where each element may contain several components in case of multi-channel arrays). The number of + * iterations (i.e. pairs swapped) is (iter_factor*mat.rows*mat.cols).round, so iter_factor=0 means + * that no shuffling is done, iter_factor=1 means that the function swaps rows(mat)*cols(mat) random * pairs etc. */ VALUE @@ -1630,7 +1630,7 @@ rb_lut(VALUE self, VALUE lut) * convert_scale(:depth => nil, :scale => 1.0, :shift => 0.0) * * Return new array with optional linear transformation. - * mat(I) = src(I) * scale + (shift, shift, ...) + * mat(I) = src(I) * scale + (shift, shift, ...) */ VALUE rb_convert_scale(VALUE self, VALUE hash) @@ -1658,7 +1658,7 @@ rb_convert_scale_abs(VALUE self, VALUE hash) { if (TYPE(hash) != T_HASH) rb_raise(rb_eTypeError, "argument should be Hash that contaion key [:depth, :scale, :shift]."); - VALUE + VALUE scale = rb_hash_aref(hash, ID2SYM(rb_intern("scale"))), shift = rb_hash_aref(hash, ID2SYM(rb_intern("shift"))), dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_8U, CV_MAT_CN(CVMAT(self)->type))); @@ -1674,7 +1674,7 @@ rb_convert_scale_abs(VALUE self, VALUE hash) * val should be CvMat or CvScalar. * If val is CvMat, it must have same type (depth and channel). * mask should be CvMat(8bit single-channel). - * For each element (I) + * For each element (I) * dst(I) = src1(I) + src2(I) if mask(I) != 0 */ VALUE @@ -1698,7 +1698,7 @@ rb_add(int argc, VALUE *argv, VALUE self) * val should be CvMat or CvScalar. * If val is CvMat, it must have same type (depth and channel). * mask should be CvMat(8bit single-channel). - * For each element (I) + * For each element (I) * dst(I) = src1(I) - src2(I) if mask(I) != 0 */ VALUE @@ -1725,7 +1725,7 @@ rb_sub(int argc, VALUE *argv, VALUE self) * val should be CvMat or CvScalar. * If val is CvMat, it must have same type (depth and channel). * For each element (I) - * dst(I) = scale * src1(I) * src2(I) + * dst(I) = scale * src1(I) * src2(I) */ VALUE rb_mul(int argc, VALUE *argv, VALUE self) @@ -1740,7 +1740,7 @@ rb_mul(int argc, VALUE *argv, VALUE self) CvScalar scl = VALUE_TO_CVSCALAR(val); VALUE mat = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvSet(CVARR(mat), scl); - cvMul(CVARR(self), CVARR(mat), CVARR(dest), NUM2DBL(scale)); + cvMul(CVARR(self), CVARR(mat), CVARR(dest), NUM2DBL(scale)); } return dest; } @@ -1751,7 +1751,7 @@ rb_mul(int argc, VALUE *argv, VALUE self) * Performs matrix multiplication * dst = src1 * src2 + shiftvec * val and shiftvec should be CvMat - * All the matrices should have the same data type and coordinated sizes. + * All the matrices should have the same data type and coordinated sizes. * Real or complex floating-point matrices are supported. */ VALUE @@ -1775,7 +1775,7 @@ rb_mat_mul(int argc, VALUE *argv, VALUE self) * val should be CvMat or CvScalar. * If val is CvMat, it must have same type (depth and channel). * For each element (I) - * dst(I) = scale * src1(I) / src2(I) + * dst(I) = scale * src1(I) / src2(I) */ VALUE rb_div(int argc, VALUE *argv, VALUE self) @@ -1784,7 +1784,7 @@ rb_div(int argc, VALUE *argv, VALUE self) if (rb_scan_args(argc, argv, "11", &val, &scale) < 2) scale = rb_float_new(1.0); dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) { + if (rb_obj_is_kind_of(val, rb_klass)) { cvDiv(CVARR(self), CVARR(val), CVARR(dest), NUM2DBL(scale)); }else{ CvScalar scl = VALUE_TO_CVSCALAR(val); @@ -1826,7 +1826,7 @@ rb_and(int argc, VALUE *argv, VALUE self) * val should be CvMat or CvScalar. * If val is CvMat, it must have same type (depth and channel). * For each element (I) - * dst(I) = src1(I) | src2(I) if mask(I) != 0 + * dst(I) = src1(I) | src2(I) if mask(I) != 0 */ VALUE rb_or(int argc, VALUE *argv, VALUE self) @@ -1913,7 +1913,7 @@ rb_cmp_internal(VALUE self, VALUE val, int operand) * eq(val) -> cvmat * * Return new matrix performed per-element comparision "equal". - * dst(I) = (self(I) == val(I) ? 0xFF : 0) + * dst(I) = (self(I) == val(I) ? 0xFF : 0) */ VALUE rb_eq(VALUE self, VALUE val) @@ -1926,7 +1926,7 @@ rb_eq(VALUE self, VALUE val) * gt(val) -> cvmat * * Return new matrix performed per-element comparision "greater than". - * dst(I) = (self(I) > val(I) ? 0xFF : 0) + * dst(I) = (self(I) > val(I) ? 0xFF : 0) */ VALUE rb_gt(VALUE self, VALUE val) @@ -1939,7 +1939,7 @@ rb_gt(VALUE self, VALUE val) * ge(val) -> cvmat * * Return new matrix performed per-element comparision "greater or equal". - * dst(I) = (self(I) >= val(I) ? 0xFF : 0) + * dst(I) = (self(I) >= val(I) ? 0xFF : 0) */ VALUE rb_ge(VALUE self, VALUE val) @@ -1952,7 +1952,7 @@ rb_ge(VALUE self, VALUE val) * lt(val) -> cvmat * * Return new matrix performed per-element comparision "less than". - * dst(I) = (self(I) < val(I) ? 0xFF : 0) + * dst(I) = (self(I) < val(I) ? 0xFF : 0) */ VALUE rb_lt(VALUE self, VALUE val) @@ -1965,7 +1965,7 @@ rb_lt(VALUE self, VALUE val) * le(val) -> cvmat * * Return new matrix performed per-element comparision "less or equal". - * dst(I) = (self(I) <= val(I) ? 0xFF : 0) + * dst(I) = (self(I) <= val(I) ? 0xFF : 0) */ VALUE rb_le(VALUE self, VALUE val) @@ -2005,7 +2005,7 @@ rb_in_range(VALUE self, VALUE min, VALUE max) tmp = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvSet(CVARR(tmp), VALUE_TO_CVSCALAR(max)); cvInRange(CVARR(self), CVARR(min), CVARR(tmp), CVARR(dest)); - }else if (rb_obj_is_kind_of(max, rb_klass)) { + }else if (rb_obj_is_kind_of(max, rb_klass)) { tmp = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvSet(CVARR(tmp), VALUE_TO_CVSCALAR(min)); cvInRange(CVARR(self), CVARR(tmp), CVARR(max), CVARR(dest)); @@ -2054,7 +2054,7 @@ rb_count_non_zero(VALUE self) * sum -> scalar * * Return summerizes elements as CvScalar. Independently for each channel. - * + * * note: If COI is setted in IplImage, the method processes the selected channel only and store the sum to the first component scalar[0]. */ VALUE @@ -2074,7 +2074,7 @@ rb_avg(int argc, VALUE *argv, VALUE self) { VALUE mask, mean; rb_scan_args(argc, argv, "01", &mask); - + return cCvScalar::new_object(cvAvg(CVARR(self), MASK(mask))); } @@ -2144,7 +2144,7 @@ rb_min_max_loc(int argc, VALUE *argv, VALUE self) * * Calculates dot product of two arrays in Euclidian metrics. * mat should be CvMat have same size and same type. - * + * * src1.src2 = sum(src1(I) * src2(I)) */ VALUE @@ -2177,7 +2177,7 @@ rb_cross_product(VALUE self, VALUE mat) * transform(transmat[,shiftvec]) -> cvmat * * performs matrix transform of every element. - * dst(I) = transmat * src(I) + shiftvec + * dst(I) = transmat * src(I) + shiftvec */ VALUE rb_transform(int argc, VALUE *argv, VALUE self) @@ -2399,7 +2399,7 @@ rb_svbksb(int argc, VALUE *argv, VALUE self) * * Computes eigenvalues and eigenvectors of symmetric matrix. * self should be symmetric square matrix. self is modified during the processing. - * + * * self * eigen_vectors(i,:)' = eigen_values(i) * eigen_vectors(i,:)' * * Currently the function is slower than #svd yet less accurate, so if self is known to be positively-defined @@ -2414,10 +2414,10 @@ rb_eigenvv(int argc, VALUE *argv, VALUE self) double eps = (NIL_P(epsilon)) ? 0.0 : NUM2DBL(epsilon); int lowidx = (NIL_P(lowindex)) ? -1 : NUM2INT(lowindex); int highidx = (NIL_P(highindex)) ? -1 : NUM2INT(highindex); - + CvSize size = cvGetSize(CVARR(self)); int type = cvGetElemType(CVARR(self)); - VALUE eigen_vectors = new_object(size, type), eigen_values = new_object(size.height, 1, type); + VALUE eigen_vectors = new_object(size, type), eigen_values = new_object(size.height, 1, type); cvEigenVV(CVARR(self), CVARR(eigen_vectors), CVARR(eigen_values), eps, lowidx, highidx); return rb_ary_new3(2, eigen_vectors, eigen_values); } @@ -2472,10 +2472,10 @@ VALUE rb_dft(int argc, VALUE *argv, VALUE self) { int type = CV_DXT_FORWARD; - if (argc > 0) { + if (argc > 0) { for (int i = 0; i < argc; i++) { type |= CVMETHOD("DXT_FLAG", argv[i]); - } + } } VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvDFT(CVARR(self), CVARR(dest), type); @@ -2500,7 +2500,7 @@ VALUE rb_dct(int argc, VALUE *argv, VALUE self) { int type = CV_DXT_FORWARD; - if (argc > 0) { + if (argc > 0) { for (int i = 0; i < argc; i++) { type |= CVMETHOD("DXT_FLAG", argv[i]); } @@ -2555,8 +2555,8 @@ rb_line_bang(int argc, VALUE *argv, VALUE self) VALUE p1, p2, drawing_option; rb_scan_args(argc, argv, "21", &p1, &p2, &drawing_option); drawing_option = DRAWING_OPTION(drawing_option); - cvLine(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), - DO_COLOR(drawing_option), + cvLine(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), + DO_COLOR(drawing_option), DO_THICKNESS(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); @@ -2569,7 +2569,7 @@ rb_line_bang(int argc, VALUE *argv, VALUE self) * * Return image is drawn a rectangle with two opposite corners p1 and p2. * - * drawing_options should be Hash include these keys. + * drawing_options should be Hash include these keys. * :color * Line color. * :thickness @@ -2594,7 +2594,7 @@ rb_rectangle(int argc, VALUE *argv, VALUE self) /* * call-seq: * rectangle!(p1, p2[, drawing_option]) -> self - * + * * Draws simple, thick or filled rectangle. * Same as CvMat#rectangle, but modifies the receiver in place. * see CvMat#rectangle @@ -2605,8 +2605,8 @@ rb_rectangle_bang(int argc, VALUE *argv, VALUE self) VALUE p1, p2, drawing_option; rb_scan_args(argc, argv, "21", &p1, &p2, &drawing_option); drawing_option = DRAWING_OPTION(drawing_option); - cvRectangle(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), - DO_COLOR(drawing_option), + cvRectangle(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), + DO_COLOR(drawing_option), DO_THICKNESS(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); @@ -2708,7 +2708,7 @@ rb_ellipse_bang(int argc, VALUE *argv, VALUE self) cvEllipse(CVARR(self), VALUE_TO_CVPOINT(center), VALUE_TO_CVSIZE(axis), NUM2DBL(angle), NUM2DBL(start_angle), NUM2DBL(end_angle), - DO_COLOR(drawing_option), + DO_COLOR(drawing_option), DO_THICKNESS(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); @@ -2759,7 +2759,7 @@ rb_ellipse_box_bang(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "11", &box, &drawing_option); drawing_option = DRAWING_OPTION(drawing_option); cvEllipseBox(CVARR(self), VALUE_TO_CVBOX2D(box), - DO_COLOR(drawing_option), + DO_COLOR(drawing_option), DO_THICKNESS(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); @@ -2797,7 +2797,7 @@ rb_fill_poly(int argc, VALUE *argv, VALUE self) * :shift * Number of fractional bits in the vertex coordinates. * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. + * note: drawing_option's default value is CvMat::DRAWING_OPTION. */ VALUE rb_fill_poly_bang(int argc, VALUE *argv, VALUE self) @@ -2822,12 +2822,12 @@ rb_fill_poly_bang(int argc, VALUE *argv, VALUE self) p[j][i] = VALUE_TO_CVPOINT(rb_ary_entry(points, i)); } } - + cvFillPoly(CVARR(self), p, num_points, num_polygons, - DO_COLOR(drawing_option), + DO_COLOR(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); @@ -2839,9 +2839,9 @@ rb_fill_poly_bang(int argc, VALUE *argv, VALUE self) * fill_convex_poly(points[,drawing_option]) -> mat * * Return image is filled convex polygon interior. - * This method is much faster than The function CvMat#fill_poly + * This method is much faster than The function CvMat#fill_poly * and can fill not only the convex polygons but any monotonic polygon, - * i.e. a polygon whose contour intersects every horizontal line (scan line) + * i.e. a polygon whose contour intersects every horizontal line (scan line) * twice at the most. * * drawing_options should be Hash include these keys. @@ -2889,7 +2889,7 @@ rb_fill_convex_poly_bang(int argc, VALUE *argv, VALUE self) cvFillConvexPoly(CVARR(self), p, num_points, - DO_COLOR(drawing_option), + DO_COLOR(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); return self; @@ -2965,8 +2965,8 @@ rb_poly_line_bang(int argc, VALUE *argv, VALUE self) num_points, num_polygons, DO_IS_CLOSED(drawing_option), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); @@ -2977,7 +2977,7 @@ rb_poly_line_bang(int argc, VALUE *argv, VALUE self) /* * call-seq: * put_text(str, point, font[,color]) -> cvmat - * + * * Return image is drawn text string. * font should be CvFont object. */ @@ -2997,7 +2997,7 @@ VALUE rb_put_text_bang(int argc, VALUE *argv, VALUE self) { VALUE text, point, font, color; - rb_scan_args(argc, argv, "22", &text, &point, &font, &color); + rb_scan_args(argc, argv, "22", &text, &point, &font, &color); cvPutText(CVARR(self), StringValueCStr(text), VALUE_TO_CVPOINT(point), CVFONT(font), *CVSCALAR(color)); return self; } @@ -3196,7 +3196,7 @@ rbi_find_corner_sub_pix(int argc, VALUE *argv, VALUE self) */ VALUE rb_good_features_to_track(int argc, VALUE *argv, VALUE self) -{ +{ VALUE quality_level, min_distance, good_features_to_track_option; CvMat *eigen, *tmp; int i; @@ -3239,7 +3239,7 @@ rb_sample_line(int argc, VALUE *argv, VALUE self) VALUE p1, p2, connectivity; if (rb_scan_args(argc, argv, "21", &p1, &p2, &connectivity) < 3) connectivity = INT2FIX(8); - CvPoint point1 = VALUE_TO_CVPOINT(p1), point2 = VALUE_TO_CVPOINT(p2); + CvPoint point1 = VALUE_TO_CVPOINT(p1), point2 = VALUE_TO_CVPOINT(p2); int size; switch(FIX2INT(connectivity)) { case 4: @@ -3266,7 +3266,7 @@ rb_sample_line(int argc, VALUE *argv, VALUE self) /* * call-seq: - * rect_sub_pix(center,size) -> cvmat + * rect_sub_pix(center[, size = self.size]) -> cvmat * * Retrieves pixel rectangle from image with sub-pixel accuracy. * Extracts pixels from self. @@ -3277,26 +3277,41 @@ rb_sample_line(int argc, VALUE *argv, VALUE self) * In this case, the replication border mode is used to get pixel values beyond the image boundaries. */ VALUE -rb_rect_sub_pix(VALUE self, VALUE center, VALUE size) +rb_rect_sub_pix(int argc, VALUE *argv, VALUE self) { - VALUE dest = new_object(VALUE_TO_CVSIZE(size), cvGetElemType(CVARR(self))); + VALUE center, size; + CvSize _size; + if (rb_scan_args(argc, argv, "11", ¢er, &size) < 2) + _size = cvGetSize(CVARR(self)); + else + _size = VALUE_TO_CVSIZE(size); + + VALUE dest = new_object(_size, cvGetElemType(CVARR(self))); cvGetRectSubPix(CVARR(self), CVARR(dest), VALUE_TO_CVPOINT2D32F(center)); return dest; } /* * call-seq: - * quandrangle_sub_pix(map_matrix) -> cvmat + * quandrangle_sub_pix(map_matrix[, size = self.size]) -> cvmat * * Retrives pixel quadrangle from image with sub-pixel accuracy. * Extracts pixel from self at sub-pixel accuracy and store them: */ VALUE -rb_quadrangle_sub_pix(VALUE self, VALUE map_matrix, VALUE size) +rb_quadrangle_sub_pix(int argc, VALUE *argv, VALUE self) { + VALUE map_matrix, size; + CvSize _size; + if (rb_scan_args(argc, argv, "11", &map_matrix, &size) < 2) + _size = cvGetSize(CVARR(self)); + else + _size = VALUE_TO_CVSIZE(size); + if (!rb_obj_is_kind_of(map_matrix, cCvMat::rb_class())) rb_raise(rb_eTypeError, "argument 1 (map matrix) should be %s (2x3).", rb_class2name(cCvMat::rb_class())); - VALUE dest = new_object(VALUE_TO_CVSIZE(size), cvGetElemType(CVARR(self))); + + VALUE dest = new_object(_size, cvGetElemType(CVARR(self))); cvGetQuadrangleSubPix(CVARR(self), CVARR(dest), CVMAT(map_matrix)); return dest; } @@ -3384,7 +3399,7 @@ rb_warp_perspective(int argc, VALUE *argv, VALUE self) if (rb_scan_args(argc, argv, "13", &map_matrix, &interpolation, &option, &fillval) < 4) fillval = INT2FIX(0); if (!rb_obj_is_kind_of(map_matrix, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (map matrix) should be %s (3x3).", rb_class2name(cCvMat::rb_class())); + rb_raise(rb_eTypeError, "argument 1 (map matrix) should be %s (3x3).", rb_class2name(cCvMat::rb_class())); VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvWarpPerspective(CVARR(self), CVARR(dest), CVMAT(map_matrix), CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR) | CVMETHOD("WARP_FLAG", option, CV_WARP_FILL_OUTLIERS), VALUE_TO_CVSCALAR(fillval)); @@ -3399,7 +3414,7 @@ rb_warp_perspective(int argc, VALUE *argv, VALUE self) * Transforms source image using the specified map: * dst(x,y)<-src(mapx(x,y),mapy(x,y)) * Similar to other geometrical transformations, some interpolation method (specified by user) is used to - * extract pixels with non-integer coordinates. + * extract pixels with non-integer coordinates. */ VALUE rb_remap(int argc, VALUE *argv, VALUE self) @@ -3409,7 +3424,7 @@ rb_remap(int argc, VALUE *argv, VALUE self) fillval = INT2FIX(0); if (!rb_obj_is_kind_of(mapx, cCvMat::rb_class())) rb_raise(rb_eTypeError, "argument 1 (map of x-coordinates) should be %s(CV_32F and single-channel).", rb_class2name(cCvMat::rb_class())); - if (!rb_obj_is_kind_of(mapy, cCvMat::rb_class())) + if (!rb_obj_is_kind_of(mapy, cCvMat::rb_class())) rb_raise(rb_eTypeError, "argument 2 (map of y-coordinates) should be %s(CV_32F and single-channel).", rb_class2name(cCvMat::rb_class())); VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvRemap(CVARR(self), CVARR(dest), CVARR(mapx), CVARR(mapy), @@ -3480,7 +3495,7 @@ rb_erode_bang(int argc, VALUE *argv, VALUE self) */ VALUE rb_dilate(int argc, VALUE *argv, VALUE self) -{ +{ return rb_dilate_bang(argc, argv, rb_clone(self)); } @@ -3512,7 +3527,7 @@ rb_morphology_open(int argc, VALUE *argv, VALUE self) { VALUE element, iteration, dest; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_OPEN, IF_INT(iteration, 1)); return dest; } @@ -3529,7 +3544,7 @@ rb_morphology_close(int argc, VALUE *argv, VALUE self) { VALUE element, iteration, dest; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_CLOSE, IF_INT(iteration, 1)); return dest; } @@ -3546,8 +3561,8 @@ rb_morphology_gradient(int argc, VALUE *argv, VALUE self) { VALUE element, iteration, temp, dest; rb_scan_args(argc, argv, "02", &element, &iteration); - temp = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + temp = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvMorphologyEx(CVARR(self), CVARR(dest), CVARR(temp), IPLCONVKERNEL(element), CV_MOP_GRADIENT, IF_INT(iteration, 1)); return dest; } @@ -3564,7 +3579,7 @@ rb_morphology_tophat(int argc, VALUE *argv, VALUE self) { VALUE element, iteration, dest; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_TOPHAT, IF_INT(iteration, 1)); return dest; } @@ -3581,7 +3596,7 @@ rb_morphology_blackhat(int argc, VALUE *argv, VALUE self) { VALUE element, iteration, dest; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_BLACKHAT, IF_INT(iteration, 1)); return dest; } @@ -3616,7 +3631,7 @@ rb_smooth_blur_no_scale(int argc, VALUE *argv, VALUE self) default: rb_raise(rb_eNotImpError, "unsupport format. (support 8bit unsigned/signed or 32bit floating point only)"); } - dest = new_object(cvGetSize(CVARR(self)), dest_type); + dest = new_object(cvGetSize(CVARR(self)), dest_type); cvSmooth(CVARR(self), CVARR(dest), CV_BLUR_NO_SCALE, IF_INT(p1, 3), IF_INT(p2, 0)); return dest; } @@ -3891,12 +3906,12 @@ rb_threshold_to_zero_inverse(int argc, VALUE *argv, VALUE self) /* * call-seq: * pyr_down([filter = :gaussian_5x5]) -> cvmat - * + * * Return downsamples image. * * This operation performs downsampling step of Gaussian pyramid decomposition. * First it convolves source image with the specified filter and then downsamples the image by rejecting even rows and columns. - * + * * note: filter - only :gaussian_5x5 is currently supported. */ VALUE @@ -3907,7 +3922,7 @@ rb_pyr_down(int argc, VALUE *argv, VALUE self) int filter = CV_GAUSSIAN_5x5; if (argc > 0) { switch (TYPE(filter_type)) { - case T_SYMBOL: + case T_SYMBOL: // currently suport CV_GAUSSIAN_5x5 only. break; default: @@ -3974,12 +3989,12 @@ rb_pyr_up(int argc, VALUE *argv, VALUE self) * where src(x',y') is value of one of pixel neighbors. * That is, to be added to the connected component, a pixel's color/brightness should be close enough to: * * color/brightness of one of its neighbors that are already referred to the connected component in case of floating range - * * color/brightness of the seed point in case of fixed range. + * * color/brightness of the seed point in case of fixed range. * * arguments - * * seed_point -The starting point. + * * seed_point -The starting point. * * new_val - New value of repainted domain pixels. - * * lo_diff - Maximal lower brightness/color difference between the currently observed pixel and one of its neighbor belong to the component or seed pixel to add the pixel to component. In case of 8-bit color images it is packed value. + * * lo_diff - Maximal lower brightness/color difference between the currently observed pixel and one of its neighbor belong to the component or seed pixel to add the pixel to component. In case of 8-bit color images it is packed value. * * up_diff - Maximal upper brightness/color difference between the currently observed pixel and one of its neighbor belong to the component or seed pixel to add the pixel to component. In case of 8-bit color images it is packed value. * * and flood_fill_option @@ -4039,14 +4054,14 @@ rb_flood_fill_bang(int argc, VALUE *argv, VALUE self) * * Finds contours in binary image, and return contours as CvContour or CvChain. * If contours not found, return nil. - * + * * flood_fill_option should be Hash include these keys. * :mode - Retrieval mode. * :external - retrive only the extreme outer contours * :list - retrieve all the contours and puts them in the list.(default) * :ccomp - retrieve all the contours and organizes them into two-level hierarchy: * top level are external boundaries of the components, second level are bounda boundaries of the holes - * :tree - retrieve all the contours and reconstructs the full hierarchy of nested contours + * :tree - retrieve all the contours and reconstructs the full hierarchy of nested contours * Connectivity determines which neighbors of a pixel are considered. * :method - Approximation method. * :code - output contours in the Freeman chain code. All other methods output polygons (sequences of vertices). @@ -4082,7 +4097,7 @@ rb_find_contours(int argc, VALUE *argv, VALUE self) * Finds contours in binary image. * The function modifies the source image content. * (Because the copy is not made, it is slightly faster than find_contours.) - * + * * see find_contours * * support single-channel 8bit unsigned image only. @@ -4156,7 +4171,7 @@ rb_pyr_segmentation(int argc, VALUE *argv, VALUE self) dest = cIplImage::new_object(cvGetSize(src), cvGetElemType(src)); CvSeq *comp = 0; storage = cCvMemStorage::new_object(); - + cvPyrSegmentation(src, IPLIMAGE(dest), CVMEMSTORAGE(storage), @@ -4173,11 +4188,11 @@ rb_pyr_segmentation(int argc, VALUE *argv, VALUE self) * * Does meanshift image segmentation. * - * sp - The spatial window radius. - * sr - The color window radius. - * max_level - Maximum level of the pyramid for the segmentation. - * termcrit - Termination criteria: when to stop meanshift iterations. - * + * sp - The spatial window radius. + * sr - The color window radius. + * max_level - Maximum level of the pyramid for the segmentation. + * termcrit - Termination criteria: when to stop meanshift iterations. + * * This method is implements the filtering stage of meanshift segmentation, * that is, the output of the function is the filtered "posterized" image with color gradients and fine-grain texture flattened. * At every pixel (X,Y) of the input image (or down-sized input image, see below) @@ -4255,8 +4270,8 @@ rb_moments(int argc, VALUE *argv, VALUE self) * hough_line_standard(rho, theta, threshold) -> cvseq(include CvLine) * * Finds lines in binary image using standard(classical) Hough transform. - * * rho - Distance resolution in pixel-related units. - * * theta - Angle resolution measured in radians. + * * rho - Distance resolution in pixel-related units. + * * theta - Angle resolution measured in radians. * * threshold - Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold. */ VALUE @@ -4276,8 +4291,8 @@ rb_hough_lines_standard(int argc, VALUE *argv, VALUE self) * hough_line_probabilistic(rho, theta, threshold, min_length, max_gap) -> cvseq(include CvTwoPoints) * * Finds lines in binary image using probabilistic Hough transform. - * * rho - Distance resolution in pixel-related units. - * * theta - Angle resolution measured in radians. + * * rho - Distance resolution in pixel-related units. + * * theta - Angle resolution measured in radians. * * threshold - Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold. * * min_length - The minimum line length. * * max_gap - The maximum gap between line segments lieing on the same line to treat them as the single line segment (i.e. to join them). @@ -4300,8 +4315,8 @@ rb_hough_lines_probabilistic(int argc, VALUE *argv, VALUE self) * hough_line_multi_scale(rho, theta, threshold, div_rho, div_theta) -> cvseq(include CvLine) * * Finds lines in binary image using multi-scale variant of classical Hough transform. - * * rho - Distance resolution in pixel-related units. - * * theta - Angle resolution measured in radians. + * * rho - Distance resolution in pixel-related units. + * * theta - Angle resolution measured in radians. * * threshold - Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold. * * div_rho = divisor for distance resolution rho. * * div_theta = divisor for angle resolution theta. @@ -4354,7 +4369,7 @@ rb_inpaint_ns(VALUE self, VALUE mask, VALUE radius) VALUE dest; if (!(rb_obj_is_kind_of(mask, cCvMat::rb_class())) || cvGetElemType(CVARR(mask)) != CV_8UC1) rb_raise(rb_eTypeError, "argument 1 (mask) should be mask image."); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvInpaint(CVARR(self), CVARR(mask), CVARR(dest), NUM2DBL(radius), CV_INPAINT_NS); return dest; } @@ -4428,7 +4443,7 @@ rb_equalize_hist(VALUE self) * * :ccoeff_normed * R(x,y)=sumx',y'[T'(x',y')*I'(x+x',y+y')]/sqrt[sumx',y'T'(x',y')2*sumx',y'I'(x+x',y+y')2] * - * After the match_template finishes comparison, the best matches can be found as global + * After the match_template finishes comparison, the best matches can be found as global * minimums (:sqdiff*) or maximums(:ccorr* or :ccoeff*) using minmax function. * In case of color image and template summation in both numerator and each sum in denominator * is done over all the channels (and separate mean values are used for each channel). @@ -4442,7 +4457,7 @@ rb_match_template(int argc, VALUE *argv, VALUE self) rb_raise(rb_eTypeError, "argument 1 (template) should be %s.", rb_class2name(cCvMat::rb_class())); if (cvGetElemType(CVARR(self)) != cvGetElemType(CVARR(templ))) rb_raise(rb_eTypeError, "template should be same type of self."); - CvSize src_size = cvGetSize(CVARR(self)), template_size = cvGetSize(CVARR(self)); + CvSize src_size = cvGetSize(CVARR(self)), template_size = cvGetSize(CVARR(self)); result = cCvMat::new_object(cvSize(src_size.width - template_size.width + 1, src_size.height - template_size.height + 1), CV_32FC1); @@ -4519,7 +4534,7 @@ rb_match_shapes_i3(int argc, VALUE *argv, VALUE self) VALUE rb_mean_shift(VALUE self, VALUE window, VALUE criteria) { - VALUE comp = cCvConnectedComp::new_object(); + VALUE comp = cCvConnectedComp::new_object(); cvMeanShift(CVARR(self), VALUE_TO_CVRECT(window), VALUE_TO_CVTERMCRITERIA(criteria), CVCONNECTEDCOMP(comp)); return comp; } @@ -4550,7 +4565,7 @@ rb_cam_shift(VALUE self, VALUE window, VALUE criteria) * that depends on contour shape (the smoother contour is, the smaller internal energy is) * and external energy that depends on the energy field and reaches minimum at the local energy * extremums that correspond to the image edges in case of image gradient. - + * The parameter criteria.epsilon is used to define the minimal number of points that must be moved * during any iteration to keep the iteration process running. * @@ -4558,11 +4573,11 @@ rb_cam_shift(VALUE self, VALUE window, VALUE criteria) * the function performed criteria.max_iter iterations, the function terminates. * * points - * Contour points (snake). + * Contour points (snake). * alpha * Weight[s] of continuity energy, single float or array of length floats, one per each contour point. * beta - * Weight[s] of curvature energy, similar to alpha. + * Weight[s] of curvature energy, similar to alpha. * gamma * Weight[s] of image energy, similar to alpha. * window @@ -4583,7 +4598,7 @@ rb_snake_image(int argc, VALUE *argv, VALUE self) int length = CVPOINTS_FROM_POINT_SET(points, &pointset); int coeff = (TYPE(alpha) == T_ARRAY || TYPE(beta) == T_ARRAY || TYPE(gamma) == T_ARRAY) ? CV_ARRAY : CV_VALUE; float *a = 0, *b = 0, *c = 0; - IplImage stub; + IplImage stub; if(coeff == CV_VALUE){ a = ALLOC(float); a[0] = (float)NUM2DBL(alpha); @@ -4596,7 +4611,7 @@ rb_snake_image(int argc, VALUE *argv, VALUE self) // todo } CvSize w = VALUE_TO_CVSIZE(window); - CvTermCriteria tc = VALUE_TO_CVTERMCRITERIA(criteria); + CvTermCriteria tc = VALUE_TO_CVTERMCRITERIA(criteria); cvSnakeImage(cvGetImage(CVARR(self), &stub), pointset, length, a, b, c, coeff, w, tc, IF_BOOL(calc_gradient, 1, 0, 1)); storage = cCvMemStorage::new_object(); @@ -4613,7 +4628,7 @@ rb_snake_image(int argc, VALUE *argv, VALUE self) * Return horizontal component of the optical flow and vertical component of the optical flow. * prev is previous image * velx is previous velocity field of x-axis, and vely is previous velocity field of y-axis. - * + * * options * * :lambda -> should be Float (default is 0.0005) * Lagrangian multiplier. @@ -4693,11 +4708,11 @@ rb_optical_flow_lk(int argc, VALUE *argv, VALUE self) * Size of the scanned neighborhood in pixels around block. * note: option's default value is CvMat::OPTICAL_FLOW_BM_OPTION. * - * Velocity is computed for every block, but not for every pixel, + * Velocity is computed for every block, but not for every pixel, * so velocity image pixels correspond to input image blocks. * input/output velocity field's size should be (self.width / block_size.width)x(self.height / block_size.height). * e.g. image.size is 320x240 and block_size is 4x4, velocity field's size is 80x60. - * + * */ VALUE rb_optical_flow_bm(int argc, VALUE *argv, VALUE self) @@ -4753,7 +4768,7 @@ rb_find_fundamental_mat_7point(int argc, VALUE *argv, VALUE klass) if(FFM_WITH_STATUS(option)){ status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_7POINT, 0, 0, CVMAT(status)); - return rb_ary_new3(2, fundamental_matrix, status); + return rb_ary_new3(2, fundamental_matrix, status); }else{ num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_7POINT, 0, 0, NULL); return fundamental_matrix; @@ -4784,7 +4799,7 @@ rb_find_fundamental_mat_8point(int argc, VALUE *argv, VALUE klass) fundamental_matrix = cCvMat::new_object(3, 3, CV_32FC1); if(FFM_WITH_STATUS(option)){ status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_8POINT, 0, 0, CVMAT(status)); + num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_8POINT, 0, 0, CVMAT(status)); return num == 0 ? Qnil : rb_ary_new3(2, fundamental_matrix, status); }else{ num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_8POINT, 0, 0, NULL); @@ -4820,7 +4835,7 @@ rb_find_fundamental_mat_ransac(int argc, VALUE *argv, VALUE klass) fundamental_matrix = cCvMat::new_object(3, 3, CV_32FC1); if(FFM_WITH_STATUS(option)){ status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_RANSAC, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), CVMAT(status)); + num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_RANSAC, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), CVMAT(status)); return num == 0 ? Qnil : rb_ary_new3(2, fundamental_matrix, status); }else{ num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_RANSAC, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), NULL); @@ -4856,7 +4871,7 @@ rb_find_fundamental_mat_lmeds(int argc, VALUE *argv, VALUE klass) fundamental_matrix = cCvMat::new_object(3, 3, CV_32FC1); if(FFM_WITH_STATUS(option)){ status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_LMEDS, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), CVMAT(status)); + num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_LMEDS, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), CVMAT(status)); return num == 0 ? Qnil : rb_ary_new3(2, fundamental_matrix, status); }else{ num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_LMEDS, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), NULL); diff --git a/ext/cvmat.h b/ext/cvmat.h index 04b4cd0..a111a2f 100644 --- a/ext/cvmat.h +++ b/ext/cvmat.h @@ -175,8 +175,8 @@ VALUE rbi_find_corner_sub_pix(int argc, VALUE *argv, VALUE self); VALUE rb_good_features_to_track(int argc, VALUE *argv, VALUE self); VALUE rb_sample_line(int argc, VALUE *argv, VALUE self); -VALUE rb_rect_sub_pix(VALUE self, VALUE center, VALUE size); -VALUE rb_quadrangle_sub_pix(VALUE self, VALUE map_matrix, VALUE size); +VALUE rb_rect_sub_pix(int argc, VALUE *argv, VALUE self); +VALUE rb_quadrangle_sub_pix(int argc, VALUE *argv, VALUE self); VALUE rb_resize(int argc, VALUE *argv, VALUE self); VALUE rb_warp_affine(int argc, VALUE *argv, VALUE self); VALUE rb_rotation(VALUE self, VALUE center, VALUE angle, VALUE scale); diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index 20540a5..94470d0 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -# -*- mode: ruby; coding: utf-8-unix -*- +# -*- mode: ruby; coding: utf-8-unix -*- require 'test/unit' require 'opencv' require File.expand_path(File.dirname(__FILE__)) + '/helper' @@ -127,7 +127,7 @@ class TestCvMat_imageprocessing < OpenCVTestCase end def test_find_corner_sub_pix - flunk('FIXME: CvMat#corner_min_eigen_val is not implemented yet.') + flunk('FIXME: CvMat#corner_min_eigen_val is not implemented yet.') end def test_good_features_to_track @@ -193,6 +193,41 @@ class TestCvMat_imageprocessing < OpenCVTestCase mat0.good_features_to_track(0.2, 5, :max => 0) } end + + def test_sample_line + flunk('FIXME: CvMat#sample_line is not implemented yet.') + end + + def test_rect_sub_pix + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + center = CvPoint2D32f.new(mat0.width / 2, mat0.height / 2) + mat1 = mat0.rect_sub_pix(center) + mat2 = mat0.rect_sub_pix(center, mat0.size) + mat3 = mat0.rect_sub_pix(center, CvSize.new(512, 512)) + + assert_equal('b3dc0e31260dd42b5341471e23e825d3', hash_img(mat1)) + assert_equal('b3dc0e31260dd42b5341471e23e825d3', hash_img(mat2)) + assert_equal('cc27ce8f4068efedcd31c4c782c3825c', hash_img(mat3)) + end + + def test_quadrangle_sub_pix + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + angle = 60 * Math::PI / 180 + map_matrix = CvMat.new(2, 3, :cv32f, 1) + map_matrix[0] = CvScalar.new(Math.cos(angle)) + map_matrix[1] = CvScalar.new(-Math.sin(angle)) + map_matrix[2] = CvScalar.new(mat0.width * 0.5) + map_matrix[3] = CvScalar.new(-map_matrix[1][0]) + map_matrix[4] = map_matrix[0] + map_matrix[5] = CvScalar.new(mat0.height * 0.5) + + mat1 = mat0.quadrangle_sub_pix(map_matrix) + mat2 = mat0.quadrangle_sub_pix(map_matrix, mat0.size) + mat3 = mat0.quadrangle_sub_pix(map_matrix, CvSize.new(512, 512)) + + assert_equal('f170c05fa50c3ac2a762d7b3f5c4ae2f', hash_img(mat1)) + assert_equal('f170c05fa50c3ac2a762d7b3f5c4ae2f', hash_img(mat2)) + assert_equal('4d949d5083405381ad9ea09dcd95e5a2', hash_img(mat3)) + end end -