diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp index ce0fbd8..9459045 100644 --- a/ext/cvmat.cpp +++ b/ext/cvmat.cpp @@ -375,6 +375,7 @@ void define_ruby_class() rb_define_method(rb_klass, "hough_circles_gradient", RUBY_METHOD_FUNC(rb_hough_circles_gradient), -1); //rb_define_method(rb_klass, "dist_transform", RUBY_METHOD_FUNC(rb_dist_transform), -1); + rb_define_method(rb_klass, "inpaint", RUBY_METHOD_FUNC(rb_inpaint), 3); rb_define_method(rb_klass, "inpaint_ns", RUBY_METHOD_FUNC(rb_inpaint_ns), 2); rb_define_method(rb_klass, "inpaint_telea", RUBY_METHOD_FUNC(rb_inpaint_telea), 2); @@ -4524,6 +4525,29 @@ rb_hough_circles_gradient(int argc, VALUE *argv, VALUE self) return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvCircle32f::rb_class(), storage); } +/* + * call-seq: + * inpaint(inpaint_method, mask, radius) -> cvmat + * + * Inpaints the selected region in the image + * The radius of circlular neighborhood of each point inpainted that is considered by the algorithm. + */ +VALUE +rb_inpaint(VALUE self, VALUE inpaint_method, VALUE mask, VALUE radius) +{ + SUPPORT_8U_ONLY(self); + SUPPORT_C1C3_ONLY(self); + const int INVALID_TYPE = -1; + VALUE dest; + int method = CVMETHOD("INPAINT_METHOD", inpaint_method, INVALID_TYPE); + if (!(rb_obj_is_kind_of(mask, cCvMat::rb_class())) || cvGetElemType(CVARR(mask)) != CV_8UC1) + rb_raise(rb_eTypeError, "argument 1 (mask) should be mask image."); + dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + cvInpaint(CVARR(self), CVARR(mask), CVARR(dest), NUM2DBL(radius), method); + return dest; +} + + /* * call-seq: * inpaint_ns(mask, radius) -> cvmat diff --git a/ext/cvmat.h b/ext/cvmat.h index afee9b3..4b58560 100644 --- a/ext/cvmat.h +++ b/ext/cvmat.h @@ -235,6 +235,7 @@ VALUE rb_hough_lines_multi_scale(VALUE self, VALUE rho, VALUE theta, VALUE thres VALUE rb_hough_circles(int argc, VALUE *argv, VALUE self); VALUE rb_hough_circles_gradient(int argc, VALUE *argv, VALUE self); VALUE rb_dist_transform(int argc, VALUE *argv, VALUE self); +VALUE rb_inpaint(VALUE self, VALUE inpaint_method, VALUE mask, VALUE radius); VALUE rb_inpaint_ns(VALUE self, VALUE mask, VALUE radius); VALUE rb_inpaint_telea(VALUE self, VALUE mask, VALUE radius); diff --git a/ext/opencv.cpp b/ext/opencv.cpp index 4ee6fc4..4561d65 100644 --- a/ext/opencv.cpp +++ b/ext/opencv.cpp @@ -239,6 +239,10 @@ define_ruby_module() rb_define_const(rb_module, "CV_HOUGH_PROBABILISTIC", INT2FIX(CV_HOUGH_PROBABILISTIC)); rb_define_const(rb_module, "CV_HOUGH_MULTI_SCALE", INT2FIX(CV_HOUGH_MULTI_SCALE)); rb_define_const(rb_module, "CV_HOUGH_GRADIENT", INT2FIX(CV_HOUGH_GRADIENT)); + + /* 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)); VALUE inversion_method = rb_hash_new(); /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ @@ -370,6 +374,12 @@ define_ruby_module() RESIST_CVMETHOD(hough_transform_method, "multi_scale", CV_HOUGH_MULTI_SCALE); RESIST_CVMETHOD(hough_transform_method, "gradient", CV_HOUGH_GRADIENT); + VALUE inpaint_method = rb_hash_new(); + /* {:ns, :telea} : Inpaint method */ + rb_define_const(rb_module, "INPAINT_METHOD", inpaint_method); + RESIST_CVMETHOD(inpaint_method, "ns", CV_INPAINT_NS); + RESIST_CVMETHOD(inpaint_method, "telea", CV_INPAINT_TELEA); + /* color convert methods */ rb_define_module_function(rb_module, "BGR2BGRA", RUBY_METHOD_FUNC(rb_BGR2BGRA), 1); rb_define_module_function(rb_module, "RGB2RGBA", RUBY_METHOD_FUNC(rb_RGB2RGBA), 1); diff --git a/test/samples/inpaint-mask.bmp b/test/samples/inpaint-mask.bmp new file mode 100644 index 0000000..7954eb2 Binary files /dev/null and b/test/samples/inpaint-mask.bmp differ diff --git a/test/samples/lena-inpaint.jpg b/test/samples/lena-inpaint.jpg new file mode 100644 index 0000000..05d0c99 Binary files /dev/null and b/test/samples/lena-inpaint.jpg differ diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index e4736bc..f124d57 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -9,6 +9,8 @@ include OpenCV # Tests for image processing functions of OpenCV::CvMat class TestCvMat_imageprocessing < OpenCVTestCase FILENAME_LENA256x256 = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-256x256.jpg' + FILENAME_LENA_INPAINT = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-inpaint.jpg' + FILENAME_INPAINT_MASK = File.expand_path(File.dirname(__FILE__)) + '/samples/inpaint-mask.bmp' 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' @@ -1414,5 +1416,42 @@ class TestCvMat_imageprocessing < OpenCVTestCase # } # snap mat0 end + + def test_inpaint + mat = CvMat.load(FILENAME_LENA_INPAINT, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + mask = CvMat.load(FILENAME_INPAINT_MASK, CV_LOAD_IMAGE_GRAYSCALE) + + [CV_INPAINT_NS, :ns].each { |method| + result_ns = mat.inpaint(method, mask, 10) + assert_equal('d3df4dda8642c83512fb417ffa5e1457', hash_img(result_ns)) + } + [CV_INPAINT_TELEA, :telea].each { |method| + result_telea = mat.inpaint(method, mask, 10) + assert_equal('d45bec22d03067578703f2ec68567167', hash_img(result_telea)) + } + + # Uncomment the following lines to show the results + # result_ns = mat.inpaint(:ns, mask, 10) + # result_telea = mat.inpaint(:telea, mask, 10) + # snap mat, result_ns, result_telea + end + + def test_inpaint_ns + mat = CvMat.load(FILENAME_LENA_INPAINT, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + mask = CvMat.load(FILENAME_INPAINT_MASK, CV_LOAD_IMAGE_GRAYSCALE) + result = mat.inpaint_ns(mask, 10) + assert_equal('d3df4dda8642c83512fb417ffa5e1457', hash_img(result)) + # Uncomment the following lines to show the result + # snap mat, result + end + + def test_inpaint_telea + mat = CvMat.load(FILENAME_LENA_INPAINT, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + mask = CvMat.load(FILENAME_INPAINT_MASK, CV_LOAD_IMAGE_GRAYSCALE) + result = mat.inpaint_telea(mask, 10) + assert_equal('d45bec22d03067578703f2ec68567167', hash_img(result)) + # Uncomment the following lines to show the result + # snap mat, result + end end diff --git a/test/test_opencv.rb b/test/test_opencv.rb index 73a632d..09a63ee 100755 --- a/test/test_opencv.rb +++ b/test/test_opencv.rb @@ -76,6 +76,10 @@ class TestOpenCV < OpenCVTestCase assert_equal(1, CV_HOUGH_PROBABILISTIC) assert_equal(2, CV_HOUGH_MULTI_SCALE) assert_equal(3, CV_HOUGH_GRADIENT) + + # Inpaint method + assert_equal(0, CV_INPAINT_NS) + assert_equal(1, CV_INPAINT_TELEA) end def test_symbols @@ -176,6 +180,10 @@ class TestOpenCV < OpenCVTestCase assert_equal(1, HOUGH_TRANSFORM_METHOD[:probabilistic]) assert_equal(2, HOUGH_TRANSFORM_METHOD[:multi_scale]) assert_equal(3, HOUGH_TRANSFORM_METHOD[:gradient]) + + # Inpaint method + assert_equal(0, INPAINT_METHOD[:ns]) + assert_equal(1, INPAINT_METHOD[:telea]) end def test_cvt_color_funcs