From b9092881ac15896e9eafbfa4da5cd0b96de786f9 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Sat, 29 Jan 2011 20:07:36 +0900 Subject: [PATCH] implemented CvMat#morphology, and modified CvMat#morphology_* --- ext/cvmat.cpp | 73 ++++++++++++++++++++---------- ext/cvmat.h | 1 + ext/opencv.cpp | 7 +++ test/test_cvmat_imageprocessing.rb | 10 ++++ test/test_opencv.rb | 7 +++ 5 files changed, 74 insertions(+), 24 deletions(-) diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp index 6485d94..9aff17e 100644 --- a/ext/cvmat.cpp +++ b/ext/cvmat.cpp @@ -330,6 +330,7 @@ void define_ruby_class() rb_define_method(rb_klass, "erode!", RUBY_METHOD_FUNC(rb_erode_bang), -1); rb_define_method(rb_klass, "dilate", RUBY_METHOD_FUNC(rb_dilate), -1); rb_define_method(rb_klass, "dilate!", RUBY_METHOD_FUNC(rb_dilate_bang), -1); + rb_define_method(rb_klass, "morphology", RUBY_METHOD_FUNC(rb_morphology), -1); rb_define_method(rb_klass, "morphology_open", RUBY_METHOD_FUNC(rb_morphology_open), -1); rb_define_method(rb_klass, "morphology_close", RUBY_METHOD_FUNC(rb_morphology_close), -1); rb_define_method(rb_klass, "morphology_gradient", RUBY_METHOD_FUNC(rb_morphology_gradient), -1); @@ -3421,7 +3422,7 @@ rb_warp_perspective(int argc, VALUE *argv, VALUE self) rb_raise(rb_eTypeError, "argument 1 (map matrix) should be %s (3x3).", rb_class2name(cCvMat::rb_class())); VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); cvWarpPerspective(CVARR(self), CVARR(dest), CVMAT(map_matrix), - CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR) | CVMETHOD("WARP_FLAG", option, CV_WARP_FILL_OUTLIERS), VALUE_TO_CVSCALAR(fillval)); + CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR) | CVMETHOD("WARP_FLAG",option, CV_WARP_FILL_OUTLIERS), VALUE_TO_CVSCALAR(fillval)); return dest; } @@ -3534,6 +3535,44 @@ rb_dilate_bang(int argc, VALUE *argv, VALUE self) return self; } +VALUE +rb_morphology_internal(VALUE element, VALUE iteration, int operation, VALUE self) +{ + CvArr* self_ptr = CVARR(self); + CvSize size = cvGetSize(self_ptr); + VALUE dest = new_object(size, cvGetElemType(self_ptr)); + if (operation == CV_MOP_GRADIENT) { + CvMat* temp = cvCreateMat(size.height, size.width, cvGetElemType(self_ptr)); + cvMorphologyEx(self_ptr, CVARR(dest), temp, IPLCONVKERNEL(element), CV_MOP_GRADIENT, IF_INT(iteration, 1)); + cvReleaseMat(&temp); + } + else { + cvMorphologyEx(self_ptr, CVARR(dest), 0, IPLCONVKERNEL(element), operation, IF_INT(iteration, 1)); + } + return dest; +} + +/* + * call-seq: + * morpholohy(operation[,element = nil][,iteration = 1]) -> cvmat + * + * Performs advanced morphological transformations. + * operation + * Type of morphological operation, one of: + * CV_MOP_OPEN - opening + * CV_MOP_CLOSE - closing + * CV_MOP_GRADIENT - morphological gradient + * CV_MOP_TOPHAT - top hat + * CV_MOP_BLACKHAT - black hat + */ +VALUE +rb_morphology(int argc, VALUE *argv, VALUE self) +{ + VALUE element, iteration, operation; + rb_scan_args(argc, argv, "12", &operation, &element, &iteration); + return rb_morphology_internal(element, iteration, FIX2INT(operation), self); +} + /* * call-seq: * morpholohy_open([element = nil][,iteration = 1]) -> cvmat @@ -3544,11 +3583,9 @@ rb_dilate_bang(int argc, VALUE *argv, VALUE self) VALUE rb_morphology_open(int argc, VALUE *argv, VALUE self) { - VALUE element, iteration, dest; + VALUE element, iteration; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_OPEN, IF_INT(iteration, 1)); - return dest; + return rb_morphology_internal(element, iteration, CV_MOP_OPEN, self); } /* @@ -3561,11 +3598,9 @@ rb_morphology_open(int argc, VALUE *argv, VALUE self) VALUE rb_morphology_close(int argc, VALUE *argv, VALUE self) { - VALUE element, iteration, dest; + VALUE element, iteration; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_CLOSE, IF_INT(iteration, 1)); - return dest; + return rb_morphology_internal(element, iteration, CV_MOP_CLOSE, self); } /* @@ -3578,15 +3613,9 @@ rb_morphology_close(int argc, VALUE *argv, VALUE self) VALUE rb_morphology_gradient(int argc, VALUE *argv, VALUE self) { - VALUE element, iteration, dest; + VALUE element, iteration; rb_scan_args(argc, argv, "02", &element, &iteration); - CvArr* self_ptr = CVARR(self); - CvSize size = cvGetSize(self_ptr); - CvMat* temp = cvCreateMat(size.height, size.width, cvGetElemType(self_ptr)); - dest = new_object(size, cvGetElemType(self_ptr)); - cvMorphologyEx(self_ptr, CVARR(dest), temp, IPLCONVKERNEL(element), CV_MOP_GRADIENT, IF_INT(iteration, 1)); - cvReleaseMat(&temp); - return dest; + return rb_morphology_internal(element, iteration, CV_MOP_GRADIENT, self); } /* @@ -3599,11 +3628,9 @@ rb_morphology_gradient(int argc, VALUE *argv, VALUE self) VALUE rb_morphology_tophat(int argc, VALUE *argv, VALUE self) { - VALUE element, iteration, dest; + VALUE element, iteration; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_TOPHAT, IF_INT(iteration, 1)); - return dest; + return rb_morphology_internal(element, iteration, CV_MOP_TOPHAT, self); } /* @@ -3618,9 +3645,7 @@ rb_morphology_blackhat(int argc, VALUE *argv, VALUE self) { VALUE element, iteration, dest; rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_BLACKHAT, IF_INT(iteration, 1)); - return dest; + return rb_morphology_internal(element, iteration, CV_MOP_BLACKHAT, self); } /* diff --git a/ext/cvmat.h b/ext/cvmat.h index b4a4fd3..326723f 100644 --- a/ext/cvmat.h +++ b/ext/cvmat.h @@ -190,6 +190,7 @@ VALUE rb_erode(int argc, VALUE *argv, VALUE self); VALUE rb_erode_bang(int argc, VALUE *argv, VALUE self); VALUE rb_dilate(int argc, VALUE *argv, VALUE self); VALUE rb_dilate_bang(int argc, VALUE *argv, VALUE self); +VALUE rb_morphology(int argc, VALUE *argv, VALUE self); VALUE rb_morphology_open(int argc, VALUE *argv, VALUE self); VALUE rb_morphology_close(int argc, VALUE *argv, VALUE self); VALUE rb_morphology_gradient(int argc, VALUE *argv, VALUE self); diff --git a/ext/opencv.cpp b/ext/opencv.cpp index b7a519b..564d397 100644 --- a/ext/opencv.cpp +++ b/ext/opencv.cpp @@ -187,6 +187,13 @@ define_ruby_module() rb_define_const(rb_module, "CV_LOAD_IMAGE_ANYDEPTH", INT2FIX(CV_LOAD_IMAGE_ANYDEPTH)); rb_define_const(rb_module, "CV_LOAD_IMAGE_ANYCOLOR", INT2FIX(CV_LOAD_IMAGE_ANYCOLOR)); + /* Types of morphological operations */ + rb_define_const(rb_module, "CV_MOP_OPEN", INT2FIX(CV_MOP_OPEN)); + rb_define_const(rb_module, "CV_MOP_CLOSE", INT2FIX(CV_MOP_CLOSE)); + rb_define_const(rb_module, "CV_MOP_GRADIENT", INT2FIX(CV_MOP_GRADIENT)); + rb_define_const(rb_module, "CV_MOP_TOPHAT", INT2FIX(CV_MOP_TOPHAT)); + rb_define_const(rb_module, "CV_MOP_BLACKHAT", INT2FIX(CV_MOP_BLACKHAT)); + /* Shape of the structuring elements */ rb_define_const(rb_module, "CV_SHAPE_RECT", INT2FIX(CV_SHAPE_RECT)); rb_define_const(rb_module, "CV_SHAPE_CROSS", INT2FIX(CV_SHAPE_CROSS)); diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index f7263b3..a0e4386 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -506,10 +506,12 @@ class TestCvMat_imageprocessing < OpenCVTestCase mat2 = mat0.morphology_open(nil, 2) kernel = IplConvKernel.new(5, 5, 2, 2, :cross) mat3 = mat0.morphology_open(kernel) + mat4 = mat0.morphology(CV_MOP_OPEN, kernel) assert_equal('165c36ad069db33735f0d4c2823f43b7', hash_img(mat1)) assert_equal('e5af47b2827ed20450222321c1678ed3', hash_img(mat2)) assert_equal('63ccb07cb93efb1563657f51e3d89252', hash_img(mat3)) + assert_equal('63ccb07cb93efb1563657f51e3d89252', hash_img(mat4)) end def test_morphology_close @@ -525,10 +527,12 @@ class TestCvMat_imageprocessing < OpenCVTestCase mat2 = mat0.morphology_close(nil, 2) kernel = IplConvKernel.new(5, 5, 2, 2, :cross) mat3 = mat0.morphology_close(kernel) + mat4 = mat0.morphology(CV_MOP_CLOSE, kernel) assert_equal('752914aae1cff07a2b3ce528b6ac3332', hash_img(mat1)) assert_equal('0908b8f98999a198e8a1fbc743de52e5', hash_img(mat2)) assert_equal('831c513d6ed86bce3f15c697de4a72f8', hash_img(mat3)) + assert_equal('831c513d6ed86bce3f15c697de4a72f8', hash_img(mat4)) end def test_morphology_gradient @@ -544,10 +548,12 @@ class TestCvMat_imageprocessing < OpenCVTestCase mat2 = mat0.morphology_gradient(nil, 2) kernel = IplConvKernel.new(5, 5, 2, 2, :cross) mat3 = mat0.morphology_gradient(kernel) + mat4 = mat0.morphology(CV_MOP_GRADIENT, kernel) assert_equal('e15d131ae29a58237f8d9a89669c3a47', hash_img(mat1)) assert_equal('31d158672f699f961c59908e0bd72d5c', hash_img(mat2)) assert_equal('1e8007c211d6f464cf8584e8e83b3c35', hash_img(mat3)) + assert_equal('1e8007c211d6f464cf8584e8e83b3c35', hash_img(mat4)) end def test_morphology_tophat @@ -563,10 +569,12 @@ class TestCvMat_imageprocessing < OpenCVTestCase mat2 = mat0.morphology_tophat(nil, 2) kernel = IplConvKernel.new(5, 5, 2, 2, :cross) mat3 = mat0.morphology_tophat(kernel) + mat4 = mat0.morphology(CV_MOP_TOPHAT, kernel) assert_equal('26f89a4f449ec8328499960acbfd44f2', hash_img(mat1)) assert_equal('102833c2e96eaa706eea5854d2aeaf5a', hash_img(mat2)) assert_equal('1760c5b63a52df37069164fe3e901aa4', hash_img(mat3)) + assert_equal('1760c5b63a52df37069164fe3e901aa4', hash_img(mat4)) end def test_morphology_blackhat @@ -582,10 +590,12 @@ class TestCvMat_imageprocessing < OpenCVTestCase mat2 = mat0.morphology_blackhat(nil, 2) kernel = IplConvKernel.new(5, 5, 2, 2, :cross) mat3 = mat0.morphology_blackhat(kernel) + mat4 = mat0.morphology(CV_MOP_BLACKHAT, kernel) assert_equal('3773d2802aad82c91ea8e14a324e5fc3', hash_img(mat1)) assert_equal('3fc6bc283fa952e1fd566944d94b3e9a', hash_img(mat2)) assert_equal('18b1d51637b912a38133341ee006c6ff', hash_img(mat3)) + assert_equal('18b1d51637b912a38133341ee006c6ff', hash_img(mat4)) end def test_smooth_blur_no_scale diff --git a/test/test_opencv.rb b/test/test_opencv.rb index 59c5f42..de5bcbc 100755 --- a/test/test_opencv.rb +++ b/test/test_opencv.rb @@ -29,6 +29,13 @@ class TestOpenCV < OpenCVTestCase assert_equal(1, CV_SHAPE_CROSS) assert_equal(2, CV_SHAPE_ELLIPSE) assert_equal(100, CV_SHAPE_CUSTOM) + + # Types of morphological operations + assert_equal(2, CV_MOP_OPEN) + assert_equal(3, CV_MOP_CLOSE) + assert_equal(4, CV_MOP_GRADIENT) + assert_equal(5, CV_MOP_TOPHAT) + assert_equal(6, CV_MOP_BLACKHAT) end def test_symbols