From faa50fdb0a379abb3bca0ef2d8af6abb3d6169d4 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Thu, 15 Nov 2012 23:00:01 +0900 Subject: [PATCH 1/5] remove some incomplete functions --- ext/opencv/cvmat.cpp | 78 ------------------------------ ext/opencv/cvmat.h | 5 -- ext/opencv/pointset.cpp | 7 --- ext/opencv/pointset.h | 1 - test/test_cvmat.rb | 12 ----- test/test_cvmat_imageprocessing.rb | 4 -- test/test_pointset.rb | 4 -- 7 files changed, 111 deletions(-) diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 889800f..3932120 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -311,10 +311,7 @@ void define_ruby_class() rb_define_method(rb_klass, "invert", RUBY_METHOD_FUNC(rb_invert), -1); rb_define_singleton_method(rb_klass, "solve", RUBY_METHOD_FUNC(rb_solve), -1); rb_define_method(rb_klass, "svd", RUBY_METHOD_FUNC(rb_svd), -1); - rb_define_method(rb_klass, "svbksb", RUBY_METHOD_FUNC(rb_svbksb), -1); 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); @@ -349,7 +346,6 @@ void define_ruby_class() rb_define_private_method(rb_klass, "__find_corner_sub_pix", RUBY_METHOD_FUNC(rbi_find_corner_sub_pix), -1); 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), -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); @@ -2878,18 +2874,6 @@ rb_svd(int argc, VALUE *argv, VALUE self) return rb_ary_new3(3, w, u, v); } -/* - * call-seq: - * svbksb - * - * not yet. - */ -VALUE -rb_svbksb(int argc, VALUE *argv, VALUE self) -{ - rb_raise(rb_eNotImpError, ""); -} - /* * call-seq: * eigenvv!([eps = 0.0]) -> [eigen_vectors(cvmat), eigen_values(cvmat)] @@ -2926,31 +2910,6 @@ rb_eigenvv(int argc, VALUE *argv, VALUE self) return rb_ary_new3(2, eigen_vectors, eigen_values); } -/* - * call-seq: - * calc_covar_matrix() - * - * not yet. - * - */ -VALUE -rb_calc_covar_matrix(int argc, VALUE *argv, VALUE self) -{ - rb_raise(rb_eNotImpError, ""); -} - -/* - * call-seq: - * mahalonobis(vec, mat) -> float - * - * not yet. - */ -VALUE -rb_mahalonobis(int argc, VALUE *argv, VALUE self) -{ - rb_raise(rb_eNotImpError, ""); -} - /* * call-seq: @@ -3824,43 +3783,6 @@ rb_good_features_to_track(int argc, VALUE *argv, VALUE self) return corners; } -/* - * call-seq: - * sample_line(p1, p2[,connectivity = 8]) {|pixel| } - * - * not yet. - */ -VALUE -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); - int size; - switch(FIX2INT(connectivity)) { - case 4: - size = abs(point2.x - point1.x) + abs(point2.y - point1.y) + 1; - break; - case 8: - size = maxint(abs(point2.x - point1.x) + 1, abs(point2.y - point1.y) + 1); - break; - default: - rb_raise(rb_eArgError, "argument 3(connectivity) should be 4 or 8. 8 is default."); - } - VALUE buf = cCvMat::new_object(1, size, cvGetElemType(CVARR(self))); - cvSampleLine(CVARR(self), point1, point2, CVMAT(buf)->data.ptr, FIX2INT(connectivity)); - if (rb_block_given_p()) { - for(int i = 0; i < size; i++) { - //Data_Wrap_Struct(cCvScalar::rb_class(), 0, 0, CVMAT(buf)->data.ptr[]); - //rb_yield(cCvScalar::new_object); - } - } - return buf; - */ - return Qnil; -} /* * call-seq: diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index a120016..5c3ef26 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -132,11 +132,8 @@ VALUE rb_det(VALUE self); VALUE rb_invert(int argc, VALUE *argv, VALUE self); VALUE rb_solve(int argc, VALUE *argv, VALUE self); VALUE rb_svd(int argc, VALUE *argv, VALUE self); -VALUE rb_svbksb(int argc, VALUE *argv, VALUE self); VALUE rb_eigenvv(int argc, VALUE *argv, VALUE self); VALUE rb_eigenvv_bang(int argc, VALUE *argv, VALUE self); -VALUE rb_calc_covar_matrix(int argc, VALUE *argv, VALUE self); -VALUE rb_mahalonobis(int argc, VALUE *argv, VALUE self); VALUE rb_dft(int argc, VALUE *argv, VALUE self); VALUE rb_dct(int argc, VALUE *argv, VALUE self); @@ -172,7 +169,6 @@ VALUE rb_corner_harris(int argc, VALUE *argv, VALUE self); 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(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); @@ -208,7 +204,6 @@ VALUE rb_draw_contours_bang(int argc, VALUE *argv, VALUE self); VALUE rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2); VALUE rb_pyr_mean_shift_filtering(int argc, VALUE *argv, VALUE self); VALUE rb_watershed(VALUE self, VALUE markers); - VALUE rb_moments(int argc, VALUE *argv, VALUE self); VALUE rb_hough_lines(int argc, VALUE *argv, VALUE self); diff --git a/ext/opencv/pointset.cpp b/ext/opencv/pointset.cpp index 7a3bd1e..2520470 100644 --- a/ext/opencv/pointset.cpp +++ b/ext/opencv/pointset.cpp @@ -197,13 +197,6 @@ rb_min_enclosing_circle(VALUE self) return success ? circle : Qnil; } -VALUE -rb_calc_pgh(VALUE self) -{ - /* not yet */ - return Qnil; -} - __NAMESPACE_END_POINT_SET int diff --git a/ext/opencv/pointset.h b/ext/opencv/pointset.h index 2e59180..4b8c8b3 100644 --- a/ext/opencv/pointset.h +++ b/ext/opencv/pointset.h @@ -29,7 +29,6 @@ VALUE rb_check_contour_convexity(VALUE self); VALUE rb_convexity_defects(VALUE self, VALUE hull); VALUE rb_min_area_rect2(VALUE self); VALUE rb_min_enclosing_circle(VALUE self); -VALUE rb_calc_pgh(VALUE self); __NAMESPACE_END_POINT_SET diff --git a/test/test_cvmat.rb b/test/test_cvmat.rb index cb2890e..3cf0973 100755 --- a/test/test_cvmat.rb +++ b/test/test_cvmat.rb @@ -2483,10 +2483,6 @@ class TestCvMat < OpenCVTestCase } end - def test_svdksb - flunk('FIXME: CvMat#svdksb is not implemented yet') - end - def test_eigenvv elems = [6, -2, -3, 7] m0 = create_cvmat(2, 2, :cv32f, 1) { |j, i, c| @@ -2522,14 +2518,6 @@ class TestCvMat < OpenCVTestCase } end - def test_calc_covar_matrix - flunk('FIXME: CvMat#calc_covar_matrix is not implemented yet') - end - - def test_mahalonobis - flunk('FIXME: CvMat#mahalonobis is not implemented yet') - end - def test_find_homography # Nx2 src = CvMat.new(4, 2, :cv32f, 1) diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index b969c10..ef7129e 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -273,10 +273,6 @@ class TestCvMat_imageprocessing < OpenCVTestCase mat0.good_features_to_track(0.2, 5, :use_harris => DUMMY_OBJ) 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) diff --git a/test/test_pointset.rb b/test/test_pointset.rb index 1799684..1a539a7 100755 --- a/test/test_pointset.rb +++ b/test/test_pointset.rb @@ -122,9 +122,5 @@ class TestPointSet < OpenCVTestCase @contour2.min_enclosing_circle } end - - def test_calc_pgh - flunk('FIXME: PointSet#calc_pgh is not implemented yet.') - end end From fb6f3de618f0459de16b034405be0bd8d8003782 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Fri, 16 Nov 2012 00:31:39 +0900 Subject: [PATCH 2/5] add CvMat#find_chessboard_corners --- ext/opencv/cvmat.cpp | 44 +++++++++++++++++++++++++++++ ext/opencv/cvmat.h | 1 + ext/opencv/opencv.cpp | 6 ++++ test/helper.rb | 1 + test/samples/chessboard.jpg | Bin 0 -> 1846 bytes test/test_cvmat_imageprocessing.rb | 28 ++++++++++++++++++ 6 files changed, 80 insertions(+) create mode 100644 test/samples/chessboard.jpg diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 3932120..657cfec 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -343,6 +343,7 @@ void define_ruby_class() rb_define_method(rb_klass, "corner_eigenvv", RUBY_METHOD_FUNC(rb_corner_eigenvv), -1); rb_define_method(rb_klass, "corner_min_eigen_val", RUBY_METHOD_FUNC(rb_corner_min_eigen_val), -1); rb_define_method(rb_klass, "corner_harris", RUBY_METHOD_FUNC(rb_corner_harris), -1); + rb_define_method(rb_klass, "find_chessboard_corners", RUBY_METHOD_FUNC(rb_find_chessboard_corners), -1); rb_define_private_method(rb_klass, "__find_corner_sub_pix", RUBY_METHOD_FUNC(rbi_find_corner_sub_pix), -1); rb_define_method(rb_klass, "good_features_to_track", RUBY_METHOD_FUNC(rb_good_features_to_track), -1); @@ -3698,6 +3699,49 @@ rb_corner_harris(int argc, VALUE *argv, VALUE self) return dest; } +/* + * call-seq: + * find_chessboard_corners(pattern_size, flag = CV_CALIB_CB_ADAPTIVE_THRESH) -> Array + * + * Returns the positions of internal corners of the chessboard. + * + * pattern_size (CvSize) - Number of inner corners per a chessboard row and column. + * flags (Integer) - Various operation flags that can be zero or a combination of the following values + * * CV_CALIB_CB_ADAPTIVE_THRESH Use adaptive thresholding to convert the image to black and white, + * rather than a fixed threshold level (computed from the average image brightness). + * * CV_CALIB_CB_NORMALIZE_IMAGE Normalize the image gamma with CvMat#equalize_hist() before applying fixed + * or adaptive thresholding. + * * CV_CALIB_CB_FILTER_QUADS Use additional criteria (like contour area, perimeter, square-like shape) + * to filter out false quads extracted at the contour retrieval stage. + * * CALIB_CB_FAST_CHECK Run a fast check on the image that looks for chessboard corners, and shortcut + * the call if none is found. This can drastically speed up the call in the degenerate condition + * when no chessboard is observed. + */ +VALUE +rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self) +{ + VALUE pattern_size_val, flag_val; + rb_scan_args(argc, argv, "11", &pattern_size_val, &flag_val); + + int flag = NIL_P(flag_val) ? CV_CALIB_CB_ADAPTIVE_THRESH : NUM2INT(flag_val); + CvSize pattern_size = VALUE_TO_CVSIZE(pattern_size_val); + CvPoint2D32f* corners = ALLOCA_N(CvPoint2D32f, pattern_size.width * pattern_size.height); + int num_found_corners = 0; + try { + cvFindChessboardCorners(CVARR(self), pattern_size, corners, &num_found_corners, flag); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + VALUE found_corners = rb_ary_new2(num_found_corners); + for (int i = 0; i < num_found_corners; i++) { + rb_ary_store(found_corners, i, cCvPoint2D32f::new_object(corners[i])); + } + + return found_corners; +} + /* * call-seq: * find_corner_sub_pix() diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index 5c3ef26..74ce98c 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -166,6 +166,7 @@ VALUE rb_pre_corner_detect(int argc, VALUE *argv, VALUE self); VALUE rb_corner_eigenvv(int argc, VALUE *argv, VALUE self); VALUE rb_corner_min_eigen_val(int argc, VALUE *argv, VALUE self); VALUE rb_corner_harris(int argc, VALUE *argv, VALUE self); +VALUE rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self); VALUE rbi_find_corner_sub_pix(int argc, VALUE *argv, VALUE self); VALUE rb_good_features_to_track(int argc, VALUE *argv, VALUE self); diff --git a/ext/opencv/opencv.cpp b/ext/opencv/opencv.cpp index af8a3db..944132d 100644 --- a/ext/opencv/opencv.cpp +++ b/ext/opencv/opencv.cpp @@ -330,6 +330,12 @@ define_ruby_module() rb_define_const(rb_module, "CV_DXT_INVERSE_SCALE", INT2FIX(CV_DXT_INVERSE_SCALE)); rb_define_const(rb_module, "CV_DXT_ROWS", INT2FIX(CV_DXT_ROWS)); + /* FindChessboardCorners flags */ + rb_define_const(rb_module, "CV_CALIB_CB_ADAPTIVE_THRESH", INT2FIX(CV_CALIB_CB_ADAPTIVE_THRESH)); + rb_define_const(rb_module, "CV_CALIB_CB_NORMALIZE_IMAGE", INT2FIX(CV_CALIB_CB_NORMALIZE_IMAGE)); + rb_define_const(rb_module, "CV_CALIB_CB_FILTER_QUADS", INT2FIX(CV_CALIB_CB_FILTER_QUADS)); + rb_define_const(rb_module, "CV_CALIB_CB_FAST_CHECK", INT2FIX(CV_CALIB_CB_FAST_CHECK)); + VALUE inversion_method = rb_hash_new(); /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ diff --git a/test/helper.rb b/test/helper.rb index 82405bd..da58720 100755 --- a/test/helper.rb +++ b/test/helper.rb @@ -13,6 +13,7 @@ class OpenCVTestCase < Test::Unit::TestCase FILENAME_LENA_EYES = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-eyes.jpg' FILENAME_FRUITS = SAMPLE_DIR + 'fruits.jpg' FILENAME_CONTOURS = File.expand_path(File.dirname(__FILE__)) + '/samples/contours.jpg' + FILENAME_CHESSBOARD = SAMPLE_DIR + 'chessboard.jpg' HAARCASCADE_FRONTALFACE_ALT = SAMPLE_DIR + 'haarcascade_frontalface_alt.xml.gz' AVI_SAMPLE = SAMPLE_DIR + 'movie_sample.avi' diff --git a/test/samples/chessboard.jpg b/test/samples/chessboard.jpg new file mode 100644 index 0000000000000000000000000000000000000000..53ca1dd51b183ee5de256040a21074f2423fe8a8 GIT binary patch literal 1846 zcmex=jKe5@ci+Wc+`GK^){8Mh0ZS!Nv-dP!(WgU}R!tMUrM?VrFDv6$>*jox1swqo9x? zP?-ptW}rbJQ9)EAL87-9c$gW17BdSn*fY#Oz`!8>iy{621GByL%O}&frPYR-@cend zd{W%anO{RV8Wld*8V_-1;ylV2AVPepRZzojE_$p#x|j2oO?3zzPNi z*8Lk5{{*{z{8s1N$^U4UdH?2591YRGh2)Q#MiVxyH8W`f=z(WdX9kE_O zD0IjGhF$veTANAV&YWMh#9=#v36$Xe!@$5+SAO}Ve$JU+t6aDdOi+;TKL8@rzu&Q+ z`r@9``HTA={#oz#Nvy7Mf#l!s{7E7NxZ)<4i)!tPbfT3_`{qMiWKgt1(X8O;7 zB`IgHVFdCE&ino*~ Date: Fri, 16 Nov 2012 01:19:14 +0900 Subject: [PATCH 3/5] add CvMat#find_corner_sub_pix --- ext/opencv/cvmat.cpp | 51 +++++++++++++++++++----------- ext/opencv/cvmat.h | 2 +- test/test_cvmat_imageprocessing.rb | 31 +++++++++++++++++- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 657cfec..43246e1 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -344,7 +344,7 @@ void define_ruby_class() rb_define_method(rb_klass, "corner_min_eigen_val", RUBY_METHOD_FUNC(rb_corner_min_eigen_val), -1); rb_define_method(rb_klass, "corner_harris", RUBY_METHOD_FUNC(rb_corner_harris), -1); rb_define_method(rb_klass, "find_chessboard_corners", RUBY_METHOD_FUNC(rb_find_chessboard_corners), -1); - rb_define_private_method(rb_klass, "__find_corner_sub_pix", RUBY_METHOD_FUNC(rbi_find_corner_sub_pix), -1); + rb_define_method(rb_klass, "find_corner_sub_pix", RUBY_METHOD_FUNC(rb_find_corner_sub_pix), 4); rb_define_method(rb_klass, "good_features_to_track", RUBY_METHOD_FUNC(rb_good_features_to_track), -1); rb_define_method(rb_klass, "rect_sub_pix", RUBY_METHOD_FUNC(rb_rect_sub_pix), -1); @@ -3744,27 +3744,42 @@ rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self) /* * call-seq: - * find_corner_sub_pix() + * find_corner_sub_pix(corners, win_size, zero_zone, criteria) -> Array * - * Refines corner locations. - * This method iterates to find the sub-pixel accurate location of corners, - * or radial saddle points, as shown in on the picture below. + * Returns refined corner locations. + * + * corners - Initial coordinates of the input corners and refined coordinates provided for output. + * win_size - Half of the side length of the search window. + * zero_zone - Half of the size of the dead region in the middle of the search zone over + * which the summation in the formula below is not done. + * criteria - Criteria for termination of the iterative process of corner refinement. */ VALUE -rbi_find_corner_sub_pix(int argc, VALUE *argv, VALUE self) +rb_find_corner_sub_pix(VALUE self, VALUE corners, VALUE win_size, VALUE zero_zone, VALUE criteria) { - /* - VALUE corners, win, zero_zone, criteria; - rb_scan_args(argc, argv, "13", &corners, &win, &zero_zone, &criteria); - if (!rb_obj_is_kind_of(corners, mPointSet::rb_module())) - rb_raise(rb_eTypeError, "argument 1 (corners) should be %s.", rb_class2name(mPointSet::rb_module())); - int count = CVSEQ(corners)->total; - VALUE storage = cCvMemStorage::new_object(); - CvPoint2D32f *pointset = POINTSET2D32f(corners); - //cvFindCornerSubPix(CVARR(self), pointset, count, VALUE_TO_CVSIZE(win), VALUE_TO_CVSIZE(zero_zone), VALUE_TO_CVTERMCRITERIA(criteria)); - //return cCvSeq::new_sequence(); - */ - return Qnil; + Check_Type(corners, T_ARRAY); + int count = RARRAY_LEN(corners); + CvPoint2D32f* corners_buff = ALLOCA_N(CvPoint2D32f, count); + VALUE* corners_ptr = RARRAY_PTR(corners); + + for (int i = 0; i < count; i++) { + corners_buff[i] = *(CVPOINT2D32F(corners_ptr[i])); + } + + try { + cvFindCornerSubPix(CVARR(self), corners_buff, count, VALUE_TO_CVSIZE(win_size), + VALUE_TO_CVSIZE(zero_zone), VALUE_TO_CVTERMCRITERIA(criteria)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + VALUE refined_corners = rb_ary_new2(count); + for (int i = 0; i < count; i++) { + rb_ary_store(refined_corners, i, cCvPoint2D32f::new_object(corners_buff[i])); + } + + return refined_corners; } /* diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index 74ce98c..33615e6 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -167,7 +167,7 @@ VALUE rb_corner_eigenvv(int argc, VALUE *argv, VALUE self); VALUE rb_corner_min_eigen_val(int argc, VALUE *argv, VALUE self); VALUE rb_corner_harris(int argc, VALUE *argv, VALUE self); VALUE rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self); -VALUE rbi_find_corner_sub_pix(int argc, VALUE *argv, VALUE self); +VALUE rb_find_corner_sub_pix(VALUE self, VALUE corners, VALUE win_size, VALUE zero_zone, VALUE criteria); VALUE rb_good_features_to_track(int argc, VALUE *argv, VALUE self); VALUE rb_rect_sub_pix(int argc, VALUE *argv, VALUE self); diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index 84444da..6923330 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -214,7 +214,36 @@ class TestCvMat_imageprocessing < OpenCVTestCase end def test_find_corner_sub_pix - flunk('FIXME: CvMat#find_corner_sub_pix is not implemented yet.') + mat = CvMat.load(FILENAME_CHESSBOARD, CV_LOAD_IMAGE_GRAYSCALE) + pattern_size = CvSize.new(4, 4) + corners = mat.find_chessboard_corners(pattern_size) + expected = [[39, 39], [79, 39], [119, 39], [159, 39], [39, 79], [79, 79], + [119, 79], [159, 78], [38, 119], [79, 119], [119, 119], [158, 118], + [39, 159], [79, 159], [119, 159], [159, 159]] + + refined_corners = mat.find_corner_sub_pix(corners, CvSize.new(3, 3), CvSize.new(-1, -1), + CvTermCriteria.new(20, 0.03)); + assert_equal(expected.size, refined_corners.size) + expected.zip(refined_corners).each { |e, a| + assert_in_delta(e[0], a.x, 3.0) + assert_in_delta(e[1], a.y, 3.0) + } + + assert_raise(TypeError) { + mat.find_corner_sub_pix(DUMMY_OBJ, CvSize.new(3, 3), CvSize.new(-1, -1), + CvTermCriteria.new(20, 0.03)); + } + assert_raise(TypeError) { + mat.find_corner_sub_pix(corners, DUMMY_OBJ, CvSize.new(-1, -1), + CvTermCriteria.new(20, 0.03)); + } + assert_raise(TypeError) { + mat.find_corner_sub_pix(corners, CvSize.new(3, 3), DUMMY_OBJ, + CvTermCriteria.new(20, 0.03)); + } + assert_raise(TypeError) { + mat.find_corner_sub_pix(corners, CvSize.new(3, 3), CvSize.new(-1, -1), DUMMY_OBJ); + } end def test_good_features_to_track From f8d9ce4a245c9d5e2e501485bb7df2f5f2709217 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Fri, 16 Nov 2012 01:52:21 +0900 Subject: [PATCH 4/5] change return values of CvMat#find_chessboard_corners Add pattern_was_found, which indicates whether the complete board was found or not. This value will be used as an argument for CvMat#draw_chessboard_corners (to be implemented). --- ext/opencv/cvmat.cpp | 11 +++++++---- test/test_cvmat_imageprocessing.rb | 16 ++++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 43246e1..e7f8ba2 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -3701,9 +3701,10 @@ rb_corner_harris(int argc, VALUE *argv, VALUE self) /* * call-seq: - * find_chessboard_corners(pattern_size, flag = CV_CALIB_CB_ADAPTIVE_THRESH) -> Array + * find_chessboard_corners(pattern_size, flag = CV_CALIB_CB_ADAPTIVE_THRESH) -> Array, Boolean> * - * Returns the positions of internal corners of the chessboard. + * Returns an array which includes the positions of internal corners of the chessboard, and + * a parameter indicating whether the complete board was found or not. * * pattern_size (CvSize) - Number of inner corners per a chessboard row and column. * flags (Integer) - Various operation flags that can be zero or a combination of the following values @@ -3727,8 +3728,9 @@ rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self) CvSize pattern_size = VALUE_TO_CVSIZE(pattern_size_val); CvPoint2D32f* corners = ALLOCA_N(CvPoint2D32f, pattern_size.width * pattern_size.height); int num_found_corners = 0; + int pattern_was_found = 0; try { - cvFindChessboardCorners(CVARR(self), pattern_size, corners, &num_found_corners, flag); + pattern_was_found = cvFindChessboardCorners(CVARR(self), pattern_size, corners, &num_found_corners, flag); } catch (cv::Exception& e) { raise_cverror(e); @@ -3739,7 +3741,8 @@ rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self) rb_ary_store(found_corners, i, cCvPoint2D32f::new_object(corners[i])); } - return found_corners; + VALUE found = (pattern_was_found > 0) ? Qtrue : Qfalse; + return rb_assoc_new(found_corners, found); } /* diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index 6923330..573c0a1 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -188,11 +188,11 @@ class TestCvMat_imageprocessing < OpenCVTestCase def test_find_chessboard_corners mat = CvMat.load(FILENAME_CHESSBOARD, CV_LOAD_IMAGE_GRAYSCALE) pattern_size = CvSize.new(4, 4) - corners1 = mat.find_chessboard_corners(pattern_size) - corners2 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_ADAPTIVE_THRESH) - corners3 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_NORMALIZE_IMAGE) - corners4 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_FILTER_QUADS) - corners5 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_FAST_CHECK) + corners1, found1 = mat.find_chessboard_corners(pattern_size) + corners2, found2 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_ADAPTIVE_THRESH) + corners3, found3 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_NORMALIZE_IMAGE) + corners4, found4 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_FILTER_QUADS) + corners5, found5 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_FAST_CHECK) expected = [[39, 39], [79, 39], [119, 39], [159, 39], [39, 79], [79, 79], [119, 79], [159, 78], [38, 119], [79, 119], [119, 119], [158, 118], @@ -204,6 +204,9 @@ class TestCvMat_imageprocessing < OpenCVTestCase assert_in_delta(e[1], a.y, 3.0) } } + [found1, found2, found3, found4, found5].each { |found| + assert(found) + } assert_raise(TypeError) { mat.find_chessboard_corners(DUMMY_OBJ) @@ -216,7 +219,7 @@ class TestCvMat_imageprocessing < OpenCVTestCase def test_find_corner_sub_pix mat = CvMat.load(FILENAME_CHESSBOARD, CV_LOAD_IMAGE_GRAYSCALE) pattern_size = CvSize.new(4, 4) - corners = mat.find_chessboard_corners(pattern_size) + corners, found = mat.find_chessboard_corners(pattern_size) expected = [[39, 39], [79, 39], [119, 39], [159, 39], [39, 79], [79, 79], [119, 79], [159, 78], [38, 119], [79, 119], [119, 119], [158, 118], [39, 159], [79, 159], [119, 159], [159, 159]] @@ -224,6 +227,7 @@ class TestCvMat_imageprocessing < OpenCVTestCase refined_corners = mat.find_corner_sub_pix(corners, CvSize.new(3, 3), CvSize.new(-1, -1), CvTermCriteria.new(20, 0.03)); assert_equal(expected.size, refined_corners.size) + assert(found) expected.zip(refined_corners).each { |e, a| assert_in_delta(e[0], a.x, 3.0) assert_in_delta(e[1], a.y, 3.0) From 08348ff8d3074d84324e3589e54900a630fc0b45 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Fri, 16 Nov 2012 02:00:10 +0900 Subject: [PATCH 5/5] add CvMat#draw_chessboard_corners --- ext/opencv/cvmat.cpp | 50 ++++++++++++++++++++++++++++++++++++++ ext/opencv/cvmat.h | 2 ++ test/test_cvmat_drawing.rb | 31 +++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index e7f8ba2..40f1a23 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -379,6 +379,8 @@ void define_ruby_class() rb_define_method(rb_klass, "find_contours!", RUBY_METHOD_FUNC(rb_find_contours_bang), -1); rb_define_method(rb_klass, "draw_contours", RUBY_METHOD_FUNC(rb_draw_contours), -1); rb_define_method(rb_klass, "draw_contours!", RUBY_METHOD_FUNC(rb_draw_contours_bang), -1); + rb_define_method(rb_klass, "draw_chessboard_corners", RUBY_METHOD_FUNC(rb_draw_chessboard_corners), 3); + rb_define_method(rb_klass, "draw_chessboard_corners!", RUBY_METHOD_FUNC(rb_draw_chessboard_corners_bang), 3); rb_define_method(rb_klass, "pyr_segmentation", RUBY_METHOD_FUNC(rb_pyr_segmentation), 3); rb_define_method(rb_klass, "pyr_mean_shift_filtering", RUBY_METHOD_FUNC(rb_pyr_mean_shift_filtering), -1); rb_define_method(rb_klass, "watershed", RUBY_METHOD_FUNC(rb_watershed), 1); @@ -4916,6 +4918,54 @@ rb_draw_contours_bang(int argc, VALUE *argv, VALUE self) return self; } +/* + * call-seq: + * draw_chessboard_corners(pattern_size, corners, pattern_was_found) -> nil + * + * Returns an image which is rendered the detected chessboard corners. + * + * pattern_size (CvSize) - Number of inner corners per a chessboard row and column. + * corners (Array) - Array of detected corners, the output of CvMat#find_chessboard_corners. + * pattern_was_found (Boolean)- Parameter indicating whether the complete board was found or not. + */ +VALUE +rb_draw_chessboard_corners(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found) +{ + return rb_draw_chessboard_corners_bang(copy(self), pattern_size, corners, pattern_was_found); +} + +/* + * call-seq: + * draw_chessboard_corners!(pattern_size, corners, pattern_was_found) -> self + * + * Renders the detected chessboard corners. + * + * pattern_size (CvSize) - Number of inner corners per a chessboard row and column. + * corners (Array) - Array of detected corners, the output of CvMat#find_chessboard_corners. + * pattern_was_found (Boolean)- Parameter indicating whether the complete board was found or not. + */ +VALUE +rb_draw_chessboard_corners_bang(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found) +{ + Check_Type(corners, T_ARRAY); + int count = RARRAY_LEN(corners); + CvPoint2D32f* corners_buff = ALLOCA_N(CvPoint2D32f, count); + VALUE* corners_ptr = RARRAY_PTR(corners); + for (int i = 0; i < count; i++) { + corners_buff[i] = *(CVPOINT2D32F(corners_ptr[i])); + } + + try { + int found = (pattern_was_found == Qtrue); + cvDrawChessboardCorners(CVARR(self), VALUE_TO_CVSIZE(pattern_size), corners_buff, count, found); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + /* * call-seq: * pyr_segmentation(level, threshold1, threshold2) -> [cvmat, cvseq(include cvconnectedcomp)] diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index 33615e6..4138454 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -202,6 +202,8 @@ VALUE rb_find_contours(int argc, VALUE *argv, VALUE self); VALUE rb_find_contours_bang(int argc, VALUE *argv, VALUE self); VALUE rb_draw_contours(int argc, VALUE *argv, VALUE self); VALUE rb_draw_contours_bang(int argc, VALUE *argv, VALUE self); +VALUE rb_draw_chessboard_corners(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found); +VALUE rb_draw_chessboard_corners_bang(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found); VALUE rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2); VALUE rb_pyr_mean_shift_filtering(int argc, VALUE *argv, VALUE self); VALUE rb_watershed(VALUE self, VALUE markers); diff --git a/test/test_cvmat_drawing.rb b/test/test_cvmat_drawing.rb index 09cb5e3..d36d4d7 100755 --- a/test/test_cvmat_drawing.rb +++ b/test/test_cvmat_drawing.rb @@ -289,6 +289,37 @@ class TestCvMat_drawing < OpenCVTestCase # snap ['src', mat0], ['result0', dst0], ['result1', dst1] end + def test_draw_chessboard_corners + mat0 = CvMat.load(FILENAME_CHESSBOARD, 1) + mat1 = mat0.clone + pattern_size = CvSize.new(4, 4) + + gray = mat1.BGR2GRAY + corners, found = gray.find_chessboard_corners(pattern_size) + + mat2 = mat1.draw_chessboard_corners(pattern_size, corners, found) + mat1.draw_chessboard_corners!(pattern_size, corners, found) + [mat1, mat2].each { |dst| + assert_equal(mat0.class, dst.class) + assert_equal(mat0.rows, dst.rows) + assert_equal(mat0.cols, dst.cols) + assert_equal(mat0.depth, dst.depth) + } + + assert_raise(TypeError) { + mat1.draw_chessboard_corners(DUMMY_OBJ, corners, found) + } + assert_raise(TypeError) { + mat1.draw_chessboard_corners(pattern_size, DUMMY_OBJ, found) + } + assert_nothing_raised { + mat1.draw_chessboard_corners(pattern_size, corners, DUMMY_OBJ) + } + + # Uncomment the following line to show the results + # snap mat0, mat1, mat2 + end + def test_put_text m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } m1 = m0.clone