From fb6f3de618f0459de16b034405be0bd8d8003782 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Fri, 16 Nov 2012 00:31:39 +0900 Subject: [PATCH] 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*~