diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 997cdb4..5287e4f 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -381,7 +381,6 @@ void define_ruby_class() rb_define_method(rb_klass, "draw_contours!", RUBY_METHOD_FUNC(rb_draw_contours_bang), -1); rb_define_method(rb_klass, "draw_chessboard_corners", RUBY_METHOD_FUNC(rb_draw_chessboard_corners), 3); rb_define_method(rb_klass, "draw_chessboard_corners!", RUBY_METHOD_FUNC(rb_draw_chessboard_corners_bang), 3); - rb_define_method(rb_klass, "pyr_segmentation", RUBY_METHOD_FUNC(rb_pyr_segmentation), 3); rb_define_method(rb_klass, "pyr_mean_shift_filtering", RUBY_METHOD_FUNC(rb_pyr_mean_shift_filtering), -1); rb_define_method(rb_klass, "watershed", RUBY_METHOD_FUNC(rb_watershed), 1); @@ -4959,42 +4958,6 @@ rb_draw_chessboard_corners_bang(VALUE self, VALUE pattern_size, VALUE corners, V return self; } -/* - * call-seq: - * pyr_segmentation(level, threshold1, threshold2) -> [cvmat, cvseq(include cvconnectedcomp)] - * - * Does image segmentation by pyramids. - * The pyramid builds up to the level level. - * The links between any pixel a on leveli and - * its candidate father pixel b on the adjacent level are established if - * p(c(a),c(b)) < threshold1. After the connected components are defined, they are joined into several clusters. Any two segments A and B belong to the same cluster, if - * p(c(A),c(B)) < threshold2. The input image has only one channel, then - * p(c^2,c^2)=|c^2-c^2|. If the input image has three channels (red, green and blue), then - * p(c^2,c^2)=0,3*(c^2 r-c^2 r)+0.59*(c^2 g-c^2 g)+0,11*(c^2 b-c^2 b) . There may be more than one connected component per a cluster. - * - * Return segmented image and sequence of connected components. - * support single-channel or 3-channel 8bit unsigned image only - */ -VALUE -rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2) -{ - IplImage* self_ptr = IPLIMAGE(self); - CvSeq *comp = NULL; - VALUE storage = cCvMemStorage::new_object(); - VALUE dest = Qnil; - try { - dest = cIplImage::new_object(cvGetSize(self_ptr), cvGetElemType(self_ptr)); - cvPyrSegmentation(self_ptr, IPLIMAGE(dest), CVMEMSTORAGE(storage), &comp, - NUM2INT(level), NUM2DBL(threshold1), NUM2DBL(threshold2)); - } - catch (cv::Exception& e) { - raise_cverror(e); - } - if (!comp) - comp = cvCreateSeq(CV_SEQ_CONNECTED_COMP, sizeof(CvSeq), sizeof(CvConnectedComp), CVMEMSTORAGE(storage)); - return rb_ary_new3(2, dest, cCvSeq::new_sequence(cCvSeq::rb_class(), comp, cCvConnectedComp::rb_class(), storage)); -} - /* * call-seq: * pyr_mean_shift_filtering(sp, sr[,max_level = 1][termcrit = CvTermCriteria.new(5,1)]) -> cvmat diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index fae26c6..0878d2b 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -204,7 +204,6 @@ VALUE rb_draw_contours(int argc, VALUE *argv, VALUE self); VALUE rb_draw_contours_bang(int argc, VALUE *argv, VALUE self); VALUE rb_draw_chessboard_corners(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found); VALUE rb_draw_chessboard_corners_bang(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found); -VALUE rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2); VALUE rb_pyr_mean_shift_filtering(int argc, VALUE *argv, VALUE self); VALUE rb_watershed(VALUE self, VALUE markers); VALUE rb_moments(int argc, VALUE *argv, VALUE self); diff --git a/ext/opencv/iplimage.cpp b/ext/opencv/iplimage.cpp index cf1d60e..baccc66 100644 --- a/ext/opencv/iplimage.cpp +++ b/ext/opencv/iplimage.cpp @@ -60,7 +60,7 @@ define_ruby_class() rb_define_method(rb_klass, "set_coi", RUBY_METHOD_FUNC(rb_set_coi), 1); rb_define_alias(rb_klass, "coi=", "set_coi"); rb_define_method(rb_klass, "reset_coi", RUBY_METHOD_FUNC(rb_reset_coi), 0); - + rb_define_method(rb_klass, "pyr_segmentation", RUBY_METHOD_FUNC(rb_pyr_segmentation), 3); rb_define_method(rb_klass, "smoothness", RUBY_METHOD_FUNC(rb_smoothness), -1); rb_define_singleton_method(rb_klass, "decode_image", RUBY_METHOD_FUNC(rb_decode_image), -1); @@ -591,6 +591,42 @@ high_pass_range(const IplImage *pImage, float lostPercentage, int &outLow, int & outLow = (int)(lostPercentage * outHigh); } +/* + * call-seq: + * pyr_segmentation(level, threshold1, threshold2) -> [iplimage, cvseq(include cvconnectedcomp)] + * + * Does image segmentation by pyramids. + * The pyramid builds up to the level level. + * The links between any pixel a on leveli and + * its candidate father pixel b on the adjacent level are established if + * p(c(a),c(b)) < threshold1. After the connected components are defined, they are joined into several clusters. Any two segments A and B belong to the same cluster, if + * p(c(A),c(B)) < threshold2. The input image has only one channel, then + * p(c^2,c^2)=|c^2-c^2|. If the input image has three channels (red, green and blue), then + * p(c^2,c^2)=0,3*(c^2 r-c^2 r)+0.59*(c^2 g-c^2 g)+0,11*(c^2 b-c^2 b) . There may be more than one connected component per a cluster. + * + * Return segmented image and sequence of connected components. + * support single-channel or 3-channel 8bit unsigned image only + */ +VALUE +rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2) +{ + IplImage* self_ptr = IPLIMAGE(self); + CvSeq *comp = NULL; + VALUE storage = cCvMemStorage::new_object(); + VALUE dest = Qnil; + try { + dest = cIplImage::new_object(cvGetSize(self_ptr), cvGetElemType(self_ptr)); + cvPyrSegmentation(self_ptr, IPLIMAGE(dest), CVMEMSTORAGE(storage), &comp, + NUM2INT(level), NUM2DBL(threshold1), NUM2DBL(threshold2)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + if (!comp) { + comp = cvCreateSeq(CV_SEQ_CONNECTED_COMP, sizeof(CvSeq), sizeof(CvConnectedComp), CVMEMSTORAGE(storage)); + } + return rb_ary_new3(2, dest, cCvSeq::new_sequence(cCvSeq::rb_class(), comp, cCvConnectedComp::rb_class(), storage)); +} VALUE new_object(int width, int height, int type) diff --git a/ext/opencv/iplimage.h b/ext/opencv/iplimage.h index b564794..d1c53fd 100644 --- a/ext/opencv/iplimage.h +++ b/ext/opencv/iplimage.h @@ -38,6 +38,8 @@ VALUE rb_get_coi(VALUE self); VALUE rb_set_coi(VALUE self, VALUE coi); VALUE rb_reset_coi(VALUE self); +VALUE rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2); + VALUE rb_smoothness(int argc, VALUE *argv, VALUE self); typedef enum { SMOOTH = 1, BLANK = 2, MESSY = 3 } Smoothness; Smoothness compute_smoothness(const IplImage *pFourierImage, const double lowFreqRatio, const double blankDensity, const double messyDensity, const double highFreqRatio, double &outLowDensity, double &outHighDensity); diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index 3844a29..0f78c11 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -1316,44 +1316,6 @@ class TestCvMat_imageprocessing < OpenCVTestCase } end - def test_pyr_segmentation - mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) - mat1, seq1 = mat0.pyr_segmentation(4, 255, 50) - assert_equal('ebd9bad0bbc90b1d4a25289b7d59c958', hash_img(mat1)) - assert_equal(5, seq1.total) - - img0 = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) - img0.set_roi(CvRect.new(0, 0, 256, 512)) - img2, seq2 = img0.pyr_segmentation(2, 255, 50) - assert_equal('963b26f51b14f175fbbf128e9b9e979f', hash_img(img2)) - assert_equal(11, seq2.total) - - assert_raise(CvStsAssert) { - img0.pyr_segmentation(-1, 255, 50) - } - assert_raise(CvStsAssert) { - img0.pyr_segmentation(1000, 255, 50) - } - assert_raise(CvStsAssert) { - img0.pyr_segmentation(4, -1, 50) - } - assert_raise(CvStsAssert) { - img0.pyr_segmentation(4, 255, -1) - } - assert_raise(TypeError) { - img0.pyr_segmentation(DUMMY_OBJ, 255, 50) - } - assert_raise(TypeError) { - img0.pyr_segmentation(4, DUMMY_OBJ, 50) - } - assert_raise(TypeError) { - img0.pyr_segmentation(4, 255, DUMMY_OBJ) - } - assert_raise(CvBadDepth) { - IplImage.new(10, 10, :cv32f, 2).pyr_segmentation(4, 255, 50) - } - end - def test_pyr_mean_shift_filtering mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) mat1 = mat0.pyr_mean_shift_filtering(30, 30) diff --git a/test/test_iplimage.rb b/test/test_iplimage.rb index c6eb3ee..0228709 100755 --- a/test/test_iplimage.rb +++ b/test/test_iplimage.rb @@ -198,6 +198,39 @@ class TestIplImage < OpenCVTestCase should_classify_images_as image, :blank end end + + def test_pyr_segmentation + img0 = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + img0.set_roi(CvRect.new(0, 0, 256, 512)) + img1, seq1 = img0.pyr_segmentation(2, 255, 50) + assert_equal('963b26f51b14f175fbbf128e9b9e979f', hash_img(img1)) + assert_equal(11, seq1.total) + + assert_raise(CvStsAssert) { + img0.pyr_segmentation(-1, 255, 50) + } + assert_raise(CvStsAssert) { + img0.pyr_segmentation(1000, 255, 50) + } + assert_raise(CvStsAssert) { + img0.pyr_segmentation(4, -1, 50) + } + assert_raise(CvStsAssert) { + img0.pyr_segmentation(4, 255, -1) + } + assert_raise(TypeError) { + img0.pyr_segmentation(DUMMY_OBJ, 255, 50) + } + assert_raise(TypeError) { + img0.pyr_segmentation(4, DUMMY_OBJ, 50) + } + assert_raise(TypeError) { + img0.pyr_segmentation(4, 255, DUMMY_OBJ) + } + assert_raise(CvBadDepth) { + IplImage.new(10, 10, :cv32f, 2).pyr_segmentation(4, 255, 50) + } + end end