From 18c3df787199c1658540ddd726f51b5ea21efc9c Mon Sep 17 00:00:00 2001 From: ser1zw Date: Sun, 30 Apr 2017 04:21:09 +0900 Subject: [PATCH] add Mat#median_blur! --- ext/opencv/mat.cpp | 1 + ext/opencv/mat_imgproc.cpp | 33 +++++++++++++++++++++++++++------ ext/opencv/mat_imgproc.hpp | 1 + test/test_mat_imgproc.rb | 28 ++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/ext/opencv/mat.cpp b/ext/opencv/mat.cpp index 9fc17ce..13e704c 100644 --- a/ext/opencv/mat.cpp +++ b/ext/opencv/mat.cpp @@ -1256,6 +1256,7 @@ namespace rubyopencv { rb_define_method(rb_klass, "gaussian_blur", RUBY_METHOD_FUNC(rb_gaussian_blur), -1); // in ext/opencv/mat_imgproc.cpp rb_define_method(rb_klass, "gaussian_blur!", RUBY_METHOD_FUNC(rb_gaussian_blur_bang), -1); // in ext/opencv/mat_imgproc.cpp rb_define_method(rb_klass, "median_blur", RUBY_METHOD_FUNC(rb_median_blur), 1); // in ext/opencv/mat_imgproc.cpp + rb_define_method(rb_klass, "median_blur!", RUBY_METHOD_FUNC(rb_median_blur_bang), 1); // in ext/opencv/mat_imgproc.cpp rb_define_method(rb_klass, "threshold", RUBY_METHOD_FUNC(rb_threshold), 3); // in ext/opencv/mat_imgproc.cpp rb_define_method(rb_klass, "adaptive_threshold", RUBY_METHOD_FUNC(rb_adaptive_threshold), 5); // in ext/opencv/mat_imgproc.cpp diff --git a/ext/opencv/mat_imgproc.cpp b/ext/opencv/mat_imgproc.cpp index 65bdb6f..9b62b6c 100644 --- a/ext/opencv/mat_imgproc.cpp +++ b/ext/opencv/mat_imgproc.cpp @@ -407,6 +407,13 @@ namespace rubyopencv { return self; } + cv::Mat* rb_median_blur_internal(VALUE self, VALUE ksize, cv::Mat* destptr) { + cv::Mat* selfptr = obj2mat(self); + cv::medianBlur(*selfptr, *destptr, NUM2INT(ksize)); + + return destptr; + } + /* * Blurs an image using the median filter. * @@ -417,18 +424,32 @@ namespace rubyopencv { * @opencv_func cv::medianBlur */ VALUE rb_median_blur(VALUE self, VALUE ksize) { - cv::Mat* selfptr = obj2mat(self); - cv::Mat* dstptr = NULL; + cv::Mat* destptr = new cv::Mat(); try { - dstptr = new cv::Mat(); - cv::medianBlur(*selfptr, *dstptr, NUM2INT(ksize)); + rb_median_blur_internal(self, ksize, destptr); } catch (cv::Exception& e) { - delete dstptr; + delete destptr; Error::raise(e); } - return mat2obj(dstptr, CLASS_OF(self)); + return mat2obj(destptr, CLASS_OF(self)); + } + + /* + * @overload median_blur!(ksize) + * @see #median_blur + */ + VALUE rb_median_blur_bang(VALUE self, VALUE ksize) { + cv::Mat* destptr = obj2mat(self); + try { + rb_median_blur_internal(self, ksize, destptr); + } + catch (cv::Exception& e) { + Error::raise(e); + } + + return self; } /* diff --git a/ext/opencv/mat_imgproc.hpp b/ext/opencv/mat_imgproc.hpp index acea645..95a34d1 100644 --- a/ext/opencv/mat_imgproc.hpp +++ b/ext/opencv/mat_imgproc.hpp @@ -21,6 +21,7 @@ namespace rubyopencv { VALUE rb_gaussian_blur(int argc, VALUE *argv, VALUE self); VALUE rb_gaussian_blur_bang(int argc, VALUE *argv, VALUE self); VALUE rb_median_blur(VALUE self, VALUE ksize); + VALUE rb_median_blur_bang(VALUE self, VALUE ksize); VALUE rb_threshold(VALUE self, VALUE threshold, VALUE max_value, VALUE threshold_type); VALUE rb_adaptive_threshold(VALUE self, VALUE max_value, VALUE adaptive_method, VALUE threshold_type, VALUE block_size, VALUE delta); diff --git a/test/test_mat_imgproc.rb b/test/test_mat_imgproc.rb index d312a8f..c9ebfe0 100755 --- a/test/test_mat_imgproc.rb +++ b/test/test_mat_imgproc.rb @@ -523,6 +523,34 @@ class TestCvMat < OpenCVTestCase # snap(['Original', m], ['Median blur', m2]) end + def test_median_blur_bang + m0 = Cv::Mat.ones(3, 3, Cv::CV_8U) + m0[1, 1] = Cv::Scalar.new(0) + m1 = m0.clone + m1.median_blur!(3) + + assert_equal(m0.class, m1.class) + assert_equal(m0.rows, m1.rows) + + assert_equal(m0.depth, m1.depth) + assert_equal(m0.dims, m1.dims) + assert_equal(m0.channels, m1.channels) + m1.rows.times { |r| + m1.cols.times { |c| + assert_equal(1, m1[r, c][0].to_i) + } + } + + assert_raise(TypeError) { + m0.median_blur(DUMMY_OBJ) + } + + # m = Cv::imread(FILENAME_LENA256x256, -1) + # m2 = m.clone + # m2.median_blur!(9) + # snap(['Original', m], ['Median blur', m2]) + end + def test_threshold m0 = Cv::Mat.zeros(2, 2, Cv::CV_8U) m0[0, 0] = Cv::Scalar.new(10)