diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp index 7ddfb8d..cd84376 100644 --- a/ext/cvmat.cpp +++ b/ext/cvmat.cpp @@ -417,7 +417,6 @@ rb_allocate(VALUE klass) * Number of channel is set by channel. channel should be 1..4. * */ -#include VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { @@ -2762,32 +2761,35 @@ rb_fill_poly(int argc, VALUE *argv, VALUE self) VALUE rb_fill_poly_bang(int argc, VALUE *argv, VALUE self) { - VALUE points, drawing_option; - rb_scan_args(argc, argv, "11", &points, &drawing_option); + VALUE polygons, drawing_option; + VALUE points; + int i, j; + int num_polygons; + int *num_points; + CvPoint **p; + rb_scan_args(argc, argv, "11", &polygons, &drawing_option); + // TODO: Check type of argument drawing_option = DRAWING_OPTION(drawing_option); - if (!POINT_SET_P(points)) - rb_raise(rb_eTypeError, "argument 1(points) should be %s.", cCvSeq::rb_class()); - /* // todo : draw multi-sequence polygon - CvSeq *seq = CVSEQ(points); - int contours = 1; - while(seq = seq->h_next) - contours++; - int **nps = ALLOCA_N(int*, contours); - CvPoint **ps = ALLOCA_N(CvPoint*, contours); - seq = CVSEQ(points); - for (int i = 0; i < contours; i++) { + num_polygons = RARRAY_LEN(polygons); + num_points = ALLOCA_N(int, num_polygons); + p = ALLOCA_N(CvPoint*, num_polygons); + for (j = 0; j < num_polygons; j++) { + points = rb_ary_entry(polygons, j); + num_points[j] = RARRAY_LEN(points); + p[j] = ALLOCA_N(CvPoint, num_points[j]); + for (i = 0; i < num_points[j]; i++) { + p[j][i] = VALUE_TO_CVPOINT(rb_ary_entry(points, i)); + } } - */ - int np = CVSEQ(points)->total; - VALUE tmp = cCvMat::new_object(1, np, CV_32SC2); - CvPoint *p = (CvPoint*)cvCvtSeqToArray(CVSEQ(points), CVMAT(tmp)->data.ptr, CV_WHOLE_SEQ); + cvFillPoly(CVARR(self), - &p, - &np, - 1, //contours + p, + num_points, + num_polygons, DO_COLOR(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); + return self; } @@ -2827,22 +2829,25 @@ rb_fill_convex_poly(int argc, VALUE *argv, VALUE self) * Fills convex polygon. * Same as CvMat#fill_convex_poly, but modifies the receiver in place. * - * see CvMat#fill_cnovex_poly + * see CvMat#fill_convex_poly */ VALUE rb_fill_convex_poly_bang(int argc, VALUE *argv, VALUE self) { VALUE points, drawing_option; + int i, num_points; + CvPoint *p; rb_scan_args(argc, argv, "11", &points, &drawing_option); + // TODO: Check type of argument drawing_option = DRAWING_OPTION(drawing_option); - if (!POINT_SET_P(points)) - rb_raise(rb_eTypeError, "argument 1(points) should be %s.", cCvSeq::rb_class()); - int np = CVSEQ(points)->total; - VALUE tmp = cCvMat::new_object(1, np, CV_32SC2); - CvPoint *p = (CvPoint*)cvCvtSeqToArray(CVSEQ(points), CVMAT(tmp)->data.ptr, CV_WHOLE_SEQ); + num_points = RARRAY_LEN(points); + p = ALLOCA_N(CvPoint, num_points); + for (i = 0; i < num_points; i++) + p[i] = VALUE_TO_CVPOINT(rb_ary_entry(points, i)); + cvFillConvexPoly(CVARR(self), p, - np, + num_points, DO_COLOR(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); @@ -2893,41 +2898,41 @@ rb_poly_line(int argc, VALUE *argv, VALUE self) VALUE rb_poly_line_bang(int argc, VALUE *argv, VALUE self) { - VALUE points, drawing_option; - rb_scan_args(argc, argv, "11", &points, &drawing_option); + VALUE polygons, drawing_option; + VALUE points; + int i, j; + int num_polygons; + int *num_points; + CvPoint **p; + rb_scan_args(argc, argv, "11", &polygons, &drawing_option); + // TODO: Check type of argument drawing_option = DRAWING_OPTION(drawing_option); - /* - if (!POINT_SET_P(points)) - rb_raise(rb_eTypeError, "argument 1(points) should be %s.", cCvSeq::rb_class()); - int np = CVSEQ(points)->total; - VALUE tmp = cCvMat::new_object(1, np, CV_32SC2); - CvPoint *p = (CvPoint*)cvCvtSeqToArray(CVSEQ(points), CVMAT(tmp)->data.ptr, CV_WHOLE_SEQ); - // todo: multi-sequence polygon + num_polygons = RARRAY_LEN(polygons); + num_points = ALLOCA_N(int, num_polygons); + p = ALLOCA_N(CvPoint*, num_polygons); + for (j = 0; j < num_polygons; j++) { + points = rb_ary_entry(polygons, j); + num_points[j] = RARRAY_LEN(points); + p[j] = ALLOCA_N(CvPoint, num_points[j]); + for (i = 0; i < num_points[j]; i++) { + p[j][i] = VALUE_TO_CVPOINT(rb_ary_entry(points, i)); + } + } + cvPolyLine(CVARR(self), - &p, - &np, - 1, //contour + p, + num_points, + num_polygons, DO_IS_CLOSED(drawing_option), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - */ - CvPoint *pointset = 0; - int length = CVPOINTS_FROM_POINT_SET(points, &pointset); - cvPolyLine(CVARR(self), - &pointset, - &length, - 1, //contour - DO_IS_CLOSED(drawing_option), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), DO_LINE_TYPE(drawing_option), DO_SHIFT(drawing_option)); return self; } + /* * call-seq: * put_text(str, point, font[,color]) -> cvmat diff --git a/test/test_cvmat.rb b/test/test_cvmat.rb index 5295036..f87dd4d 100755 --- a/test/test_cvmat.rb +++ b/test/test_cvmat.rb @@ -39,15 +39,6 @@ class TestCvMat < OpenCVTestCase } end - def test_DRAWING_OPTION - CvMat::DRAWING_OPTION[:color].to_ary.each { |c| - assert_in_delta(0, c, 0.01) - } - assert_equal(1, CvMat::DRAWING_OPTION[:thickness]) - assert_equal(8, CvMat::DRAWING_OPTION[:line_type]) - assert_equal(0, CvMat::DRAWING_OPTION[:shift]) - end - def test_GOOD_FEATURES_TO_TRACK_OPTION assert_equal(0xff, CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:max]) assert_nil(CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:mask]) @@ -56,12 +47,6 @@ class TestCvMat < OpenCVTestCase assert_in_delta(0.04, CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:k], 0.01) end - def test_FLOOD_FILL_OPTION - assert_equal(4, CvMat::FLOOD_FILL_OPTION[:connectivity]) - assert((not CvMat::FLOOD_FILL_OPTION[:fixed_range])) - assert((not CvMat::FLOOD_FILL_OPTION[:mask_only])) - end - def test_FIND_CONTOURS_OPTION assert_equal(1, CvMat::FIND_CONTOURS_OPTION[:mode]) assert_equal(2, CvMat::FIND_CONTOURS_OPTION[:method]) diff --git a/test/test_cvmat_drawing.rb b/test/test_cvmat_drawing.rb new file mode 100755 index 0000000..b53ffe0 --- /dev/null +++ b/test/test_cvmat_drawing.rb @@ -0,0 +1,141 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8-unix -*- +require 'test/unit' +require 'opencv' +require 'pp' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for drawing functions of OpenCV::CvMat +class TestCvMat_drawing < OpenCVTestCase + def test_DRAWING_OPTION + CvMat::DRAWING_OPTION[:color].to_ary.each { |c| + assert_in_delta(0, c, 0.01) + } + assert_equal(1, CvMat::DRAWING_OPTION[:thickness]) + assert_equal(8, CvMat::DRAWING_OPTION[:line_type]) + assert_equal(0, CvMat::DRAWING_OPTION[:shift]) + end + + def test_FLOOD_FILL_OPTION + assert_equal(4, CvMat::FLOOD_FILL_OPTION[:connectivity]) + assert((not CvMat::FLOOD_FILL_OPTION[:fixed_range])) + assert((not CvMat::FLOOD_FILL_OPTION[:mask_only])) + end + + def test_line + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.line(CvPoint.new(1, 0), CvPoint.new(m0.width - 1, m0.height - 1), + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.line!(CvPoint.new(1, 0), CvPoint.new(m0.width - 1, m0.height - 1), + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following lines to view the image + # GUI::Window.new('Line: Blue, thickness = 1').show(m1) + # GUI::Window.new('Line: Red, thickness = 3').show(m2) + # GUI::wait_key + end + + def test_rectangle + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.rectangle(CvPoint.new(20, 20), CvPoint.new(m0.width - 20, m0.height - 20), + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.rectangle!(CvPoint.new(20, 20), CvPoint.new(m0.width - 20, m0.height - 20), + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following lines to view the image + # GUI::Window.new('Rectangle: Blue, thickness = 1').show(m1) + # GUI::Window.new('Rectangle: Red, thickness = 3').show(m2) + # GUI::wait_key + end + + def test_circle + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.circle(CvPoint.new(m0.width / 2, m0.height / 2), 80, + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.circle!(CvPoint.new(m0.width / 2, m0.height / 2), 80, + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + # Uncomment the following lines to view the image + # GUI::Window.new('Circle: Blue, thickness = 1').show(m1) + # GUI::Window.new('Circle: Red, thickness = 3').show(m2) + # GUI::wait_key + end + + def test_ellipse + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.ellipse!(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following lines to view the image + # GUI::Window.new('Ellipse: Blue, thickness = 1').show(m1) + # GUI::Window.new('Ellipse: Red, thickness = 3').show(m2) + # GUI::wait_key + end + + def test_ellipse_box + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + box = CvBox2D.new(CvPoint2D32f.new(m0.width / 2, m0.height / 2), CvSize2D32f.new(120, 160), 30) + m1 = m0.clone + m2 = m0.ellipse_box(box, :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.ellipse_box!(box, :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following lines to view the image + # GUI::Window.new('Ellipse box: Blue, thickness = 1').show(m1) + # GUI::Window.new('Ellipse box: Red, thickness = 3').show(m2) + # GUI::wait_key + end + + def test_fill_poly + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + pt = [[CvPoint.new(10, 20), CvPoint.new(10, 150), CvPoint.new(100, 50)], + [CvPoint.new(200, 10), CvPoint.new(200, 200), CvPoint.new(170, 200)], + [CvPoint.new(30, 10), CvPoint.new(0, 0), CvPoint.new(90, 150)]] + + m1 = m0.clone + m2 = m0.fill_poly(pt, :color => CvColor::Red, :line_type => :aa) + m1.fill_poly!(pt, :color => CvColor::Blue, :line_type => :aa) + + # Uncomment the following lines to view the image + # GUI::Window.new('Fill poly: Blue, thickness = 1').show(m1) + # GUI::Window.new('Fill poly: Red, thickness = 3').show(m2) + # GUI::wait_key + end + + def test_fill_convex_poly + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + pt = [CvPoint.new(10, 20), CvPoint.new(10, 150), CvPoint.new(100, 50)] + + m1 = m0.clone + m2 = m0.fill_convex_poly(pt, :color => CvColor::Red, :line_type => :aa) + m1.fill_convex_poly!(pt, :color => CvColor::Blue, :line_type => :aa) + + # Uncomment the following lines to view the image + # GUI::Window.new('Fill convex poly: Blue, thickness = 1').show(m1) + # GUI::Window.new('Fill convex poly: Red, thickness = 3').show(m2) + # GUI::wait_key + end + + def test_poly_line + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + pt = [[CvPoint.new(10, 20), CvPoint.new(10, 150), CvPoint.new(100, 150), CvPoint.new(10, 20)], + [CvPoint.new(100, 200), CvPoint.new(200, 190), CvPoint.new(180, 50), CvPoint.new(100, 200)]] + + m1 = m0.clone + m2 = m0.poly_line(pt, :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.poly_line!(pt, :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following lines to view the image + # GUI::Window.new('Poly line: Blue, thickness = 1').show(m1) + # GUI::Window.new('Poly line: Red, thickness = 3').show(m2) + # GUI::wait_key + end +end + +