diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index 413c05b..ecc9763 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -347,6 +347,8 @@ void define_ruby_class() rb_define_method(rb_klass, "flood_fill!", RUBY_METHOD_FUNC(rb_flood_fill_bang), -1); rb_define_method(rb_klass, "find_contours", RUBY_METHOD_FUNC(rb_find_contours), -1); rb_define_method(rb_klass, "find_contours!", RUBY_METHOD_FUNC(rb_find_contours_bang), -1); + rb_define_method(rb_klass, "draw_contours", RUBY_METHOD_FUNC(rb_draw_contours), -1); + rb_define_method(rb_klass, "draw_contours!", RUBY_METHOD_FUNC(rb_draw_contours_bang), -1); 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); @@ -4734,6 +4736,51 @@ rb_find_contours_bang(int argc, VALUE *argv, VALUE self) return cCvSeq::new_sequence(klass, contour, element_klass, storage); } +/* + * call-seq: + * draw_contours(contour, external_color, hole_color, max_level, options) -> cvmat + * + * Draws contour outlines or interiors in an image. + * + * * contour (CvContour) - Pointer to the first contour + * * external_color (CvScalar) - Color of the external contours + * * hole_color (CvScalar) - Color of internal contours (holes) + * * max_level (Integer) - Maximal level for drawn contours. If 0, only contour is drawn. If 1, the contour and all contours following it on the same level are drawn. If 2, all contours following and all contours one level below the contours are drawn, and so forth. If the value is negative, the function does not draw the contours following after contour but draws the child contours of contour up to the |max_level| - 1 level. + * * options (Hash) - Drawing options. + * * :thickness (Integer) - Thickness of lines the contours are drawn with. If it is negative, the contour interiors are drawn (default: 1). + * * :line_type (Integer or Symbol) - Type of the contour segments, see CvMat#line description (default: 8). + */ +VALUE +rb_draw_contours(int argc, VALUE *argv, VALUE self) +{ + return rb_draw_contours_bang(argc, argv, copy(self)); +} + +/* + * call-seq: + * draw_contours!(contour, external_color, hole_color, max_level, options) -> cvmat + * + * Draws contour outlines or interiors in an image. + * + * see CvMat#draw_contours + */ +VALUE +rb_draw_contours_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE contour, external_color, hole_color, max_level, options; + rb_scan_args(argc, argv, "41", &contour, &external_color, &hole_color, &max_level, &options); + options = DRAWING_OPTION(options); + try { + cvDrawContours(CVARR(self), CVSEQ_WITH_CHECK(contour), VALUE_TO_CVSCALAR(external_color), + VALUE_TO_CVSCALAR(hole_color), NUM2INT(max_level), + DO_THICKNESS(options), DO_LINE_TYPE(options)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + /* * call-seq: * pyr_segmentation(level, threshold1, threshold2) -> [cvmat, cvseq(include cvconnectedcomp)] diff --git a/ext/opencv/cvmat.h b/ext/opencv/cvmat.h index 5298399..2b1ba31 100644 --- a/ext/opencv/cvmat.h +++ b/ext/opencv/cvmat.h @@ -200,6 +200,8 @@ VALUE rb_flood_fill(int argc, VALUE *argv, VALUE self); VALUE rb_flood_fill_bang(int argc, VALUE *argv, VALUE self); VALUE rb_find_contours(int argc, VALUE *argv, VALUE self); VALUE rb_find_contours_bang(int argc, VALUE *argv, VALUE self); +VALUE rb_draw_contours(int argc, VALUE *argv, VALUE self); +VALUE rb_draw_contours_bang(int argc, VALUE *argv, VALUE self); 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); diff --git a/test/helper.rb b/test/helper.rb index cbd3818..82405bd 100755 --- a/test/helper.rb +++ b/test/helper.rb @@ -12,9 +12,10 @@ class OpenCVTestCase < Test::Unit::TestCase FILENAME_LENA32x32 = SAMPLE_DIR + 'lena-32x32.jpg' FILENAME_LENA_EYES = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-eyes.jpg' FILENAME_FRUITS = SAMPLE_DIR + 'fruits.jpg' + FILENAME_CONTOURS = File.expand_path(File.dirname(__FILE__)) + '/samples/contours.jpg' HAARCASCADE_FRONTALFACE_ALT = SAMPLE_DIR + 'haarcascade_frontalface_alt.xml.gz' AVI_SAMPLE = SAMPLE_DIR + 'movie_sample.avi' - + DUMMY_OBJ = Digest::MD5.new # dummy object for argument type check test def snap(*images) diff --git a/test/test_cvmat_drawing.rb b/test/test_cvmat_drawing.rb index 91c4d0b..09cb5e3 100755 --- a/test/test_cvmat_drawing.rb +++ b/test/test_cvmat_drawing.rb @@ -129,7 +129,7 @@ class TestCvMat_drawing < OpenCVTestCase } assert_raise(TypeError) { m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, - :color => DUMMY_OBJ) + :color => DUMMY_OBJ) } # assert_raise(CvError) { # m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, @@ -246,6 +246,49 @@ class TestCvMat_drawing < OpenCVTestCase # m1.poly_line(pt, :line_type => DUMMY_OBJ) end + def test_draw_contours + mat0 = CvMat.load(FILENAME_CONTOURS, CV_LOAD_IMAGE_GRAYSCALE) + + mat0 = mat0.threshold(128, 255, CV_THRESH_BINARY) + contours = mat0.find_contours(:mode => CV_RETR_TREE, :method => CV_CHAIN_APPROX_SIMPLE) + dst0 = mat0.clone.clear + dst1 = mat0.clone.clear.GRAY2BGR + begin + dst0 = dst0.draw_contours!(contours, CvColor::Black, CvColor::White, -1) + dst1.draw_contours!(contours, CvColor::Red, CvColor::Blue, 2, + :thickness => -1, :line_type => :aa) + end while (contours = contours.h_next) + + [dst0, dst1].each { |dst| + assert_equal(mat0.class, dst.class) + assert_equal(mat0.rows, dst.rows) + assert_equal(mat0.cols, dst.cols) + assert_equal(mat0.depth, dst.depth) + } + + assert_raise(TypeError) { + dst0.draw_contours(DUMMY_OBJ, CvColor::Black, CvColor::White, -1) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, DUMMY_OBJ, CvColor::White, -1) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, DUMMY_OBJ, -1) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, CvColor::White, DUMMY_OBJ) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, CvColor::White, -1, :thickness => DUMMY_OBJ) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, CvColor::White, -1, :line_type => DUMMY_OBJ) + } + + # Uncomment the following line to show the results + # snap ['src', mat0], ['result0', dst0], ['result1', dst1] + end + def test_put_text m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } m1 = m0.clone diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb index 51b8b79..189a626 100755 --- a/test/test_cvmat_imageprocessing.rb +++ b/test/test_cvmat_imageprocessing.rb @@ -12,7 +12,6 @@ class TestCvMat_imageprocessing < OpenCVTestCase 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' FILENAME_LENA_EYES = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-eyes.jpg' FILENAME_STR_CV = File.expand_path(File.dirname(__FILE__)) + '/samples/str-cv.jpg'