diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp index 9459045..43bbda1 100644 --- a/ext/cvmat.cpp +++ b/ext/cvmat.cpp @@ -4620,7 +4620,7 @@ rb_equalize_hist(VALUE self) * Compares template against overlapped image regions. * method is specifies the way the template must be compared with image regions. - * method should be following symbol. (see CvMat::MATCH_TEMPLATE_METHOD 's key and value.) + * method should be following symbol. (see OpenCV::MATCH_TEMPLATE_METHOD 's key and value.) * * * :sqdiff * R(x,y)=sumx',y'[T(x',y')-I(x+x',y+y')]2 @@ -4646,16 +4646,22 @@ VALUE rb_match_template(int argc, VALUE *argv, VALUE self) { VALUE templ, method, result; - rb_scan_args(argc, argv, "11", &templ, &method); + int method_flag; + if (rb_scan_args(argc, argv, "11", &templ, &method) == 1) + method_flag = CV_TM_SQDIFF; + else + method_flag = CVMETHOD("MATCH_TEMPLATE_METHOD", method); + if (!(rb_obj_is_kind_of(templ, cCvMat::rb_class()))) 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)); - result = cCvMat::new_object(cvSize(src_size.width - template_size.width + 1, - src_size.height - template_size.height + 1), + CvSize src_size = cvGetSize(CVARR(self)); + CvSize template_size = cvGetSize(CVARR(templ)); + result = cCvMat::new_object(src_size.height - template_size.height + 1, + src_size.width - template_size.width + 1, CV_32FC1); - cvMatchTemplate(CVARR(self), CVARR(templ), CVARR(result), CVMETHOD("MATCH_TEMPLATE_METHOD", CV_TM_SQDIFF)); + cvMatchTemplate(CVARR(self), CVARR(templ), CVARR(result), method_flag); return result; } diff --git a/ext/opencv.cpp b/ext/opencv.cpp index 4561d65..99cf64b 100644 --- a/ext/opencv.cpp +++ b/ext/opencv.cpp @@ -243,6 +243,14 @@ define_ruby_module() /* Inpaint method */ rb_define_const(rb_module, "CV_INPAINT_NS", INT2FIX(CV_INPAINT_NS)); rb_define_const(rb_module, "CV_INPAINT_TELEA", INT2FIX(CV_INPAINT_TELEA)); + + /* Match template method */ + rb_define_const(rb_module, "CV_TM_SQDIFF", INT2FIX(CV_TM_SQDIFF)); + rb_define_const(rb_module, "CV_TM_SQDIFF_NORMED", INT2FIX(CV_TM_SQDIFF_NORMED)); + rb_define_const(rb_module, "CV_TM_CCORR", INT2FIX(CV_TM_CCORR)); + rb_define_const(rb_module, "CV_TM_CCORR_NORMED", INT2FIX(CV_TM_CCORR_NORMED)); + rb_define_const(rb_module, "CV_TM_CCOEFF", INT2FIX(CV_TM_CCOEFF)); + rb_define_const(rb_module, "CV_TM_CCOEFF_NORMED", INT2FIX(CV_TM_CCOEFF_NORMED)); VALUE inversion_method = rb_hash_new(); /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ diff --git a/test/samples/lena-eyes.jpg b/test/samples/lena-eyes.jpg new file mode 100644 index 0000000..e3f2caa Binary files /dev/null and b/test/samples/lena-eyes.jpg differ diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index 9e61fa3..2977bfb 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -14,6 +14,7 @@ class TestCvMat_imageprocessing < OpenCVTestCase FILENAME_LENA32x32 = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-32x32.jpg' FILENAME_CONTOURS = File.expand_path(File.dirname(__FILE__)) + '/samples/contours.jpg' FILENAME_LINES = File.expand_path(File.dirname(__FILE__)) + '/samples/lines.jpg' + FILENAME_LENA_EYES = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-eyes.jpg' def test_sobel mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) @@ -1462,5 +1463,55 @@ class TestCvMat_imageprocessing < OpenCVTestCase # Uncomment the following lines to show the result # snap mat, result end + + def test_match_template + mat = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + templ = CvMat.load(FILENAME_LENA_EYES, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + + # sqdiff + result = mat.match_template(templ) + assert_equal('88663ec44be797ca883fc87bb6d7c09b', hash_img(result)) + [CV_TM_SQDIFF, :sqdiff].each { |method| + result = mat.match_template(templ, method) + assert_equal('88663ec44be797ca883fc87bb6d7c09b', hash_img(result)) + } + + # sqdiff_normed + [CV_TM_SQDIFF_NORMED, :sqdiff_normed].each { |method| + result = mat.match_template(templ, method) + assert_equal('75c812f87184b2ccd8f83b70a8436356', hash_img(result)) + } + + # ccorr + [CV_TM_CCORR, :ccorr].each { |method| + result = mat.match_template(templ, method) + assert_equal('6ebe7e48edf8fc64bcc0fd7f1e96555c', hash_img(result)) + } + + # ccorr_normed + [CV_TM_CCORR_NORMED, :ccorr_normed].each { |method| + result = mat.match_template(templ, method) + assert_equal('4cf8ebcec870f8295d615a9aa345ae4d', hash_img(result)) + } + + # ccoeff + [CV_TM_CCOEFF, :ccoeff].each { |method| + result = mat.match_template(templ, method) + assert_equal('248a391c5a1e1dbcf7a19f3310b5cd7a', hash_img(result)) + } + + # ccoeff_normed + [CV_TM_CCOEFF_NORMED, :ccoeff_normed].each { |method| + result = mat.match_template(templ, method) + assert_equal('27a4e9b45ed648848f0498356bd2c5b5', hash_img(result)) + } + + # Uncomment the following lines to show the result + # result = mat.match_template(templ) + # pt1 = result.min_max_loc[2] # minimum location + # pt2 = CvPoint.new(pt1.x + templ.width, pt1.y + templ.height) + # mat.rectangle!(pt1, pt2, :color => CvColor::Black, :thickness => 3) + # snap mat, templ, result + end end diff --git a/test/test_opencv.rb b/test/test_opencv.rb index 09a63ee..4567e83 100755 --- a/test/test_opencv.rb +++ b/test/test_opencv.rb @@ -80,6 +80,14 @@ class TestOpenCV < OpenCVTestCase # Inpaint method assert_equal(0, CV_INPAINT_NS) assert_equal(1, CV_INPAINT_TELEA) + + # Match tempalte method + assert_equal(0, CV_TM_SQDIFF) + assert_equal(1, CV_TM_SQDIFF_NORMED) + assert_equal(2, CV_TM_CCORR) + assert_equal(3, CV_TM_CCORR_NORMED) + assert_equal(4, CV_TM_CCOEFF) + assert_equal(5, CV_TM_CCOEFF_NORMED) end def test_symbols