From c66c856e44405b2ede2f408c75543d6ad2498ab8 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Sun, 30 Jan 2011 01:07:29 +0900 Subject: [PATCH] implemented CvMat#smooth --- ext/cvmat.cpp | 31 ++++++++ ext/cvmat.h | 1 + ext/opencv.cpp | 7 ++ test/test_cvmat_imageprocessing.rb | 110 +++++++++++++++++++++++++++++ test/test_opencv.rb | 7 ++ 5 files changed, 156 insertions(+) diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp index 9aff17e..7847c19 100644 --- a/ext/cvmat.cpp +++ b/ext/cvmat.cpp @@ -337,6 +337,7 @@ void define_ruby_class() rb_define_method(rb_klass, "morphology_tophat", RUBY_METHOD_FUNC(rb_morphology_tophat), -1); rb_define_method(rb_klass, "morphology_blackhat", RUBY_METHOD_FUNC(rb_morphology_blackhat), -1); + rb_define_method(rb_klass, "smooth", RUBY_METHOD_FUNC(rb_smooth), -1); rb_define_method(rb_klass, "smooth_blur_no_scale", RUBY_METHOD_FUNC(rb_smooth_blur_no_scale), -1); rb_define_method(rb_klass, "smooth_blur", RUBY_METHOD_FUNC(rb_smooth_blur), -1); rb_define_method(rb_klass, "smooth_gaussian", RUBY_METHOD_FUNC(rb_smooth_gaussian), -1); @@ -3648,6 +3649,36 @@ rb_morphology_blackhat(int argc, VALUE *argv, VALUE self) return rb_morphology_internal(element, iteration, CV_MOP_BLACKHAT, self); } +VALUE +rb_smooth(int argc, VALUE *argv, VALUE self) +{ + VALUE smoothtype, p1, p2, p3, p4; + rb_scan_args(argc, argv, "14", &smoothtype, &p1, &p2, &p3, &p4); + int _smoothtype = FIX2INT(smoothtype); + VALUE (*smooth_func)(int c, VALUE* v, VALUE s); + switch (_smoothtype) { + case CV_BLUR_NO_SCALE: + smooth_func = rb_smooth_blur_no_scale; + break; + case CV_BLUR: + smooth_func = rb_smooth_blur; + break; + case CV_GAUSSIAN: + smooth_func = rb_smooth_gaussian; + break; + case CV_MEDIAN: + smooth_func = rb_smooth_median; + break; + case CV_BILATERAL: + smooth_func = rb_smooth_bilateral; + break; + default: + smooth_func = rb_smooth_gaussian; + break; + } + return (*smooth_func)(argc - 1, argv + 1, self); +} + /* * call-seq: * smooth_blur_no_scale([p1 = 3, p2 = 3]) -> cvmat diff --git a/ext/cvmat.h b/ext/cvmat.h index 326723f..2e35645 100644 --- a/ext/cvmat.h +++ b/ext/cvmat.h @@ -197,6 +197,7 @@ VALUE rb_morphology_gradient(int argc, VALUE *argv, VALUE self); VALUE rb_morphology_tophat(int argc, VALUE *argv, VALUE self); VALUE rb_morphology_blackhat(int argc, VALUE *argv, VALUE self); +VALUE rb_smooth(int argc, VALUE *argv, VALUE self); VALUE rb_smooth_blur_no_scale(int argc, VALUE *argv, VALUE self); VALUE rb_smooth_blur(int argc, VALUE *argv, VALUE self); VALUE rb_smooth_gaussian(int argc, VALUE *argv, VALUE self); diff --git a/ext/opencv.cpp b/ext/opencv.cpp index 564d397..cbaa324 100644 --- a/ext/opencv.cpp +++ b/ext/opencv.cpp @@ -200,6 +200,13 @@ define_ruby_module() rb_define_const(rb_module, "CV_SHAPE_ELLIPSE", INT2FIX(CV_SHAPE_ELLIPSE)); rb_define_const(rb_module, "CV_SHAPE_CUSTOM", INT2FIX(CV_SHAPE_CUSTOM)); + /* Types of the smoothing */ + rb_define_const(rb_module, "CV_BLUR_NO_SCALE", INT2FIX(CV_BLUR_NO_SCALE)); + rb_define_const(rb_module, "CV_BLUR", INT2FIX(CV_BLUR)); + rb_define_const(rb_module, "CV_GAUSSIAN", INT2FIX(CV_GAUSSIAN)); + rb_define_const(rb_module, "CV_MEDIAN", INT2FIX(CV_MEDIAN)); + rb_define_const(rb_module, "CV_BILATERAL", INT2FIX(CV_BILATERAL)); + VALUE inversion_method = rb_hash_new(); /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ rb_define_const(rb_module, "INVERSION_METHOD", inversion_method); diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index a0e4386..ad361bd 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -598,6 +598,116 @@ class TestCvMat_imageprocessing < OpenCVTestCase assert_equal('18b1d51637b912a38133341ee006c6ff', hash_img(mat4)) end + def test_smooth + mat0 = CvMat.load(FILENAME_LENA32x32, CV_LOAD_IMAGE_GRAYSCALE) + + # Blur no scale + mat1 = mat0.smooth(CV_BLUR_NO_SCALE) + mat2 = mat0.smooth(CV_BLUR_NO_SCALE, 3, 3) + mat3 = mat0.smooth(CV_BLUR_NO_SCALE, 7, 7) + mat4 = CvMat.new(32, 32, :cv32f, 1).smooth_blur_no_scale + + [mat1, mat2, mat3].each { |m| + assert_equal(1, m.channel) + assert_equal(:cv16u, m.depth) + } + assert_equal(1, mat4.channel) + assert_equal(:cv32f, mat4.depth) + + assert_equal('3c9074c87b65117798f48e41a17b2f30', hash_img(mat1)) + assert_equal('3c9074c87b65117798f48e41a17b2f30', hash_img(mat2)) + assert_equal('9c549aa406a425a65b036c2f9a2689e0', hash_img(mat3)) + + # Blur + mat1 = mat0.smooth(CV_BLUR) + mat2 = mat0.smooth(CV_BLUR, 3, 3) + mat3 = mat0.smooth(CV_BLUR, 7, 7) + mat4 = CvMat.new(32, 32, :cv16u, 1).smooth(CV_BLUR) + mat5 = CvMat.new(32, 32, :cv32f, 1).smooth(CV_BLUR) + mat6 = CvMat.new(32, 32, :cv8u, 3).smooth(CV_BLUR) + + [mat1, mat2, mat3].each { |m| + assert_equal(1, m.channel) + assert_equal(:cv8u, m.depth) + } + assert_equal(1, mat4.channel) + assert_equal(:cv16u, mat4.depth) + assert_equal(1, mat5.channel) + assert_equal(:cv32f, mat5.depth) + assert_equal(3, mat6.channel) + assert_equal(:cv8u, mat6.depth) + + assert_equal('f2473b5b964ae8950f6a7fa5cde4c67a', hash_img(mat1)) + assert_equal('f2473b5b964ae8950f6a7fa5cde4c67a', hash_img(mat2)) + assert_equal('d7bb344fc0f6ec0da4b9754d319e4e4a', hash_img(mat3)) + + # Gaussian + mat1 = mat0.smooth(CV_GAUSSIAN) + mat2 = mat0.smooth(CV_GAUSSIAN, 3, 3) + mat3 = mat0.smooth(CV_GAUSSIAN, 3, 3, 3) + mat4 = mat0.smooth(CV_GAUSSIAN, 3, 3, 3, 3) + mat5 = mat0.smooth(CV_GAUSSIAN, 7, 7, 5, 3) + + mat6 = CvMat.new(32, 32, :cv16u, 1).smooth(CV_GAUSSIAN) + mat7 = CvMat.new(32, 32, :cv32f, 1).smooth(CV_GAUSSIAN) + mat8 = CvMat.new(32, 32, :cv8u, 3).smooth(CV_GAUSSIAN) + + [mat1, mat2, mat3, mat4, mat5].each { |m| + assert_equal(1, m.channel) + assert_equal(:cv8u, m.depth) + } + assert_equal(1, mat6.channel) + assert_equal(:cv16u, mat6.depth) + assert_equal(1, mat7.channel) + assert_equal(:cv32f, mat7.depth) + assert_equal(3, mat8.channel) + assert_equal(:cv8u, mat8.depth) + + assert_equal('580c88f3e0e317a5770be3f28f31eda2', hash_img(mat1)) + assert_equal('580c88f3e0e317a5770be3f28f31eda2', hash_img(mat2)) + assert_equal('a1ffaa14522719e37d75eec18ff8b309', hash_img(mat3)) + assert_equal('a1ffaa14522719e37d75eec18ff8b309', hash_img(mat4)) + assert_equal('f7f8b4eff3240ffc8f259ce975936d92', hash_img(mat5)) + + # Median + mat0 = create_cvmat(64, 64, :cv8u, 1) { |j, i, c| + if (i + j) % 15 != 0 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + (-1..1).each { |dy| + (-1..1).each { |dx| + mat0[32 + dy, 32 + dx] = CvScalar.new(0) + } + } + + mat1 = mat0.smooth(CV_MEDIAN) + mat2 = mat0.smooth(CV_MEDIAN, 3) + mat3 = mat0.smooth(CV_MEDIAN, 7) + mat4 = CvMat.new(64, 64, :cv8u, 3).smooth(CV_MEDIAN) + + assert_equal('7343a41c542e034db356636c06134961', hash_img(mat1)) + assert_equal('7343a41c542e034db356636c06134961', hash_img(mat2)) + assert_equal('6ae59e64850377ee5470c854761551ea', hash_img(mat3)) + + # Bilateral + mat0 = create_cvmat(64, 64, :cv8u, 1) { |j, i, c| + if i > 32 + (i + j) % 15 != 0 ? CvScalar.new(32) : CvScalar.new(224) + else + (i + j) % 15 != 0 ? CvScalar.new(224) : CvScalar.new(32) + end + } + + mat1 = mat0.smooth(CV_BILATERAL) + mat2 = mat0.smooth(CV_BILATERAL, 3, 3) + mat3 = mat0.smooth(CV_BILATERAL, 7, 7) + mat4 = CvMat.new(64, 64, :cv8u, 3).smooth(CV_BILATERAL) + flunk('FIXME: Cases of CvMat#smooth(CV_BILATERAL) are not tested yet.') + end + def test_smooth_blur_no_scale mat0 = CvMat.load(FILENAME_LENA32x32, CV_LOAD_IMAGE_GRAYSCALE) diff --git a/test/test_opencv.rb b/test/test_opencv.rb index de5bcbc..78683d0 100755 --- a/test/test_opencv.rb +++ b/test/test_opencv.rb @@ -36,6 +36,13 @@ class TestOpenCV < OpenCVTestCase assert_equal(4, CV_MOP_GRADIENT) assert_equal(5, CV_MOP_TOPHAT) assert_equal(6, CV_MOP_BLACKHAT) + + # Types of the smoothing + assert_equal(0, CV_BLUR_NO_SCALE) + assert_equal(1, CV_BLUR) + assert_equal(2, CV_GAUSSIAN) + assert_equal(3, CV_MEDIAN) + assert_equal(4, CV_BILATERAL) end def test_symbols