From e56749c70df2c224137651b47733ca81f7399c2a Mon Sep 17 00:00:00 2001 From: ser1zw Date: Sun, 17 Apr 2011 02:46:23 +0900 Subject: [PATCH] modified and tested CvMat.find_fundamental_mat_*point --- ext/opencv/cvmat.cpp | 69 +++++++++++---------------------- ext/opencv/cvmat.h | 4 +- test/test_cvmat.rb | 90 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 48 deletions(-) diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index ed34cf6..8598ae7 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -394,11 +394,16 @@ void define_ruby_class() rb_define_method(rb_klass, "optical_flow_lk", RUBY_METHOD_FUNC(rb_optical_flow_lk), 2); 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); - rb_define_singleton_method(rb_klass, "find_fundamental_mat_lmeds", RUBY_METHOD_FUNC(rb_find_fundamental_mat_lmeds), -1); - rb_define_singleton_method(rb_klass, "compute_correspond_epilines", RUBY_METHOD_FUNC(rb_compute_correspond_epilines), 3); + rb_define_singleton_method(rb_klass, "find_fundamental_mat_7point", + RUBY_METHOD_FUNC(rb_find_fundamental_mat_7point), 2); + rb_define_singleton_method(rb_klass, "find_fundamental_mat_8point", + RUBY_METHOD_FUNC(rb_find_fundamental_mat_8point), 2); + rb_define_singleton_method(rb_klass, "find_fundamental_mat_ransac", + RUBY_METHOD_FUNC(rb_find_fundamental_mat_ransac), -1); + rb_define_singleton_method(rb_klass, "find_fundamental_mat_lmeds", + RUBY_METHOD_FUNC(rb_find_fundamental_mat_lmeds), -1); + rb_define_singleton_method(rb_klass, "compute_correspond_epilines", + RUBY_METHOD_FUNC(rb_compute_correspond_epilines), 3); rb_define_method(rb_klass, "save_image", RUBY_METHOD_FUNC(rb_save_image), 1); } @@ -4995,66 +5000,38 @@ rb_optical_flow_bm(int argc, VALUE *argv, VALUE self) /* * call-seq: - * CvMat.find_fundamental_mat_7point(points1, points2[,options = {}]) -> fundamental_matrix(cvmat) or nil + * CvMat.find_fundamental_mat_7point(points1, points2) -> fundamental_matrix(cvmat) or nil * * Calculates fundamental matrix from corresponding points, use for 7-point algorism. Return fundamental matrix(9x3). * points1 and points2 should be 2x7 or 3x7 single-channel, or 1x7 multi-channel matrix. - * option should be Hash include these keys. - * :with_status (true or false) - * If set true, return fundamental_matrix and status. [fundamental_matrix, status] - * Otherwise return fundamental matrix only(default). * - * note: option's default value is CvMat::FIND_FUNDAMENTAL_MAT_OPTION. * note: 9x3 fundamental matrix means 3x3 three fundamental matrices. */ VALUE -rb_find_fundamental_mat_7point(int argc, VALUE *argv, VALUE klass) +rb_find_fundamental_mat_7point(VALUE klass, VALUE points1, VALUE points2) { - VALUE points1, points2, option, fundamental_matrix, status; - int num = 0; - rb_scan_args(argc, argv, "21", &points1, &points2, &option); - option = FIND_FUNDAMENTAL_MAT_OPTION(option); - fundamental_matrix = cCvMat::new_object(9, 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_7POINT, 0, 0, CVMAT(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; - } + VALUE fundamental_matrix = cCvMat::new_object(9, 3, CVMAT(points1)->type); + int num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), + CV_FM_7POINT, 0, 0, NULL); + return (num == 0) ? Qnil : fundamental_matrix; } /* * call-seq: - * CvMat.find_fundamental_mat_8point(points1, points2[,options = {}]) -> fundamental_matrix(cvmat) or nil + * CvMat.find_fundamental_mat_8point(points1, points2) -> fundamental_matrix(cvmat) or nil * * Calculates fundamental matrix from corresponding points, use for 8-point algorism. - * points1 and points2 should be 2x7 or 3x7 single-channel, or 1x7 multi-channel matrix. - * option should be Hash include these keys. - * :with_status (true or false) - * If set true, return fundamental_matrix and status. [fundamental_matrix, status] - * Otherwise return fundamental matrix only(default). + * points1 and points2 should be 2x8 or 3x8 single-channel, or 1x8 multi-channel matrix. * - * note: option's default value is CvMat::FIND_FUNDAMENTAL_MAT_OPTION. */ VALUE -rb_find_fundamental_mat_8point(int argc, VALUE *argv, VALUE klass) +rb_find_fundamental_mat_8point(VALUE klass, VALUE points1, VALUE points2) { - VALUE points1, points2, option, fundamental_matrix, status; - int num = 0; - rb_scan_args(argc, argv, "21", &points1, &points2, &option); - option = FIND_FUNDAMENTAL_MAT_OPTION(option); - 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)); - 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); - return num == 0 ? Qnil : fundamental_matrix; - } + VALUE fundamental_matrix = cCvMat::new_object(3, 3, CVMAT(points1)->type); + int num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), + CV_FM_8POINT, 0, 0, NULL); + return (num == 0) ? Qnil : fundamental_matrix; } /* diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index 005c286..dcdcee9 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -259,8 +259,8 @@ VALUE rb_optical_flow_bm(int argc, VALUE *argv, VALUE self); VALUE rb_optical_flow_pyr_lk(int argc, VALUE *argv, VALUE self); /* Epipolar Geometory */ -VALUE rb_find_fundamental_mat_7point(int argc, VALUE *argv, VALUE klass); -VALUE rb_find_fundamental_mat_8point(int argc, VALUE *argv, VALUE klass); +VALUE rb_find_fundamental_mat_7point(VALUE klass, VALUE points1, VALUE points2); +VALUE rb_find_fundamental_mat_8point(VALUE klass, VALUE points1, VALUE points2); VALUE rb_find_fundamental_mat_ransac(int argc, VALUE *argv, VALUE klass); VALUE rb_find_fundamental_mat_lmeds(int argc, VALUE *argv, VALUE klass); VALUE rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_image, VALUE fundamental_matrix); diff --git a/test/test_cvmat.rb b/test/test_cvmat.rb index 10eb657..f9d3275 100755 --- a/test/test_cvmat.rb +++ b/test/test_cvmat.rb @@ -1846,6 +1846,96 @@ class TestCvMat < OpenCVTestCase def test_mahalonobis flunk('CvMat#mahalonobis is not implemented yet') end + + def test_find_fundamental_mat_7point + points1 = [[488.362, 169.911], + [449.488, 174.44], + [408.565, 179.669], + [364.512, 184.56], + [491.483, 122.366], + [451.512, 126.56], + [409.502, 130.342]] + points2 = [[526.605, 213.332], + [470.485, 207.632], + [417.5, 201.0], + [367.485, 195.632], + [530.673, 156.417], + [473.749, 151.39], + [419.503, 146.656]] + + mat1 = CvMat.new(7, 2, :cv64f, 1) + mat2 = CvMat.new(7, 2, :cv64f, 1) + + points1.each_with_index { |pt, i| + mat1[i, 0] = CvScalar.new(pt[0]) + mat1[i, 1] = CvScalar.new(pt[1]) + } + points2.each_with_index { |pt, i| + mat2[i, 0] = CvScalar.new(pt[0]) + mat2[i, 1] = CvScalar.new(pt[1]) + } + + f_mat = CvMat.find_fundamental_mat_7point(mat1, mat2) + + assert_equal(9, f_mat.rows) + assert_equal(3, f_mat.cols) + + expected = [0.000009, 0.000029, -0.010343, + -0.000033, 0.000000, 0.014590, + 0.004415, -0.013420, 1.000000, + 0.000000, 0.000001, -0.000223, + -0.000001, 0.000036, -0.005309, + -0.000097, -0.006463, 1.000000, + 0.000002, 0.000005, -0.001621, + -0.000005, 0.000031, -0.002559, + 0.000527, -0.007424, 1.000000] + expected.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 1.0e-5) + } + end + + def test_find_fundamental_mat_8point + points1 = [[488.362, 169.911], + [449.488, 174.44], + [408.565, 179.669], + [364.512, 184.56], + [491.483, 122.366], + [451.512, 126.56], + [409.502, 130.342], + [365.5, 134]] + points2 = [[526.605, 213.332], + [470.485, 207.632], + [417.5, 201.0], + [367.485, 195.632], + [530.673, 156.417], + [473.749, 151.39], + [419.503, 146.656], + [368.669, 142.565]] + + mat1 = CvMat.new(8, 2, :cv64f, 1) + mat2 = CvMat.new(8, 2, :cv64f, 1) + + points1.each_with_index { |pt, i| + mat1[i, 0] = CvScalar.new(pt[0]) + mat1[i, 1] = CvScalar.new(pt[1]) + } + points2.each_with_index { |pt, i| + mat2[i, 0] = CvScalar.new(pt[0]) + mat2[i, 1] = CvScalar.new(pt[1]) + } + + f_mat = CvMat.find_fundamental_mat_8point(mat1, mat2) + + assert_equal(3, f_mat.rows) + assert_equal(3, f_mat.cols) + + expected = [0.000001, 0.000004, -0.001127, + -0.000005, 0.000038, -0.003778, + 0.000819, -0.008325, 1.000000] + expected.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 1.0e-5) + } + end end