1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

add CvMat#find_chessboard_corners

This commit is contained in:
ser1zw 2012-11-16 00:31:39 +09:00
parent faa50fdb0a
commit fb6f3de618
6 changed files with 80 additions and 0 deletions

View file

@ -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<CvPoint2D32f>
*
* 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(<i></i>)

View file

@ -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);

View file

@ -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 */

View file

@ -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'

BIN
test/samples/chessboard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -185,6 +185,34 @@ class TestCvMat_imageprocessing < OpenCVTestCase
}
end
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)
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]]
[corners1, corners2, corners3, corners4, corners5].each { |corners|
assert_equal(expected.size, corners.size)
expected.zip(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_chessboard_corners(DUMMY_OBJ)
}
assert_raise(TypeError) {
mat.find_chessboard_corners(pattern_size, DUMMY_OBJ)
}
end
def test_find_corner_sub_pix
flunk('FIXME: CvMat#find_corner_sub_pix is not implemented yet.')
end