From e760e91d71b748201c2398b4560feeb9a8590c18 Mon Sep 17 00:00:00 2001 From: ser1zw Date: Fri, 2 Mar 2012 02:15:06 +0900 Subject: [PATCH] fix IplImage#split to return Array (Issue #7) https://github.com/ruby-opencv/ruby-opencv/issues/7 --- ext/opencv/cvmat.cpp | 23 +++++++++++++---------- test/helper.rb | 13 +++++++++++++ test/test_cvmat.rb | 28 +++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp index dc65f32..413c05b 100644 --- a/ext/opencv/cvmat.cpp +++ b/ext/opencv/cvmat.cpp @@ -1588,22 +1588,25 @@ rb_flip_bang(int argc, VALUE *argv, VALUE self) VALUE rb_split(VALUE self) { - CvMat* self_ptr = CVMAT(self); - int type = self_ptr->type, depth = CV_MAT_DEPTH(type), channel = CV_MAT_CN(type); - CvMat *dest[] = { NULL, NULL, NULL, NULL }; + CvArr* self_ptr = CVARR(self); + int type = cvGetElemType(self_ptr); + int depth = CV_MAT_DEPTH(type), channel = CV_MAT_CN(type); + VALUE dest = rb_ary_new2(channel); try { + CvArr *dest_ptr[] = { NULL, NULL, NULL, NULL }; CvSize size = cvGetSize(self_ptr); - for (int i = 0; i < channel; ++i) - dest[i] = rb_cvCreateMat(size.height, size.width, CV_MAKETYPE(depth, 1)); - cvSplit(self_ptr, dest[0], dest[1], dest[2], dest[3]); + for (int i = 0; i < channel; ++i) { + VALUE tmp = new_mat_kind_object(size, self, depth, 1); + rb_ary_store(dest, i, tmp); + dest_ptr[i] = CVARR(tmp); + } + cvSplit(self_ptr, dest_ptr[0], dest_ptr[1], dest_ptr[2], dest_ptr[3]); } catch (cv::Exception& e) { raise_cverror(e); } - VALUE ary = rb_ary_new2(channel); - for (int i = 0; i < channel; ++i) - rb_ary_store(ary, i, OPENCV_OBJECT(rb_klass, dest[i])); - return ary; + + return dest; } /* diff --git a/test/helper.rb b/test/helper.rb index 24afdd1..cbd3818 100755 --- a/test/helper.rb +++ b/test/helper.rb @@ -99,6 +99,19 @@ class OpenCVTestCase < Test::Unit::TestCase m end + def create_iplimage(width, height, depth = :cv8u, channel = 4, &block) + m = IplImage.new(width, height, depth, channel) + block = lambda { |j, i, c| CvScalar.new(*([c + 1] * channel)) } unless block_given? + count = 0 + height.times { |j| + width.times { |i| + m[j, i] = block.call(j, i, count) + count += 1 + } + } + m + end + def assert_each_cvscalar(actual, delta = 0, &block) raise unless block_given? count = 0 diff --git a/test/test_cvmat.rb b/test/test_cvmat.rb index c71fa65..2e00109 100755 --- a/test/test_cvmat.rb +++ b/test/test_cvmat.rb @@ -826,9 +826,14 @@ class TestCvMat < OpenCVTestCase m0 = create_cvmat(2, 3, :cv8u, 3) { |j, i, c| CvScalar.new(c * 10, c * 20, c * 30) } - m0.split.each_with_index { |m, idx| + + splitted = m0.split + assert_equal(m0.channel, splitted.size) + splitted.each_with_index { |m, idx| + assert_equal(CvMat, m.class) assert_equal(m0.height, m.height) assert_equal(m0.width, m.width) + assert_equal(1, m.channel) c = 0 m0.height.times { |j| @@ -839,6 +844,27 @@ class TestCvMat < OpenCVTestCase } } } + + # IplImage#split should return Array + image = create_iplimage(2, 3, :cv8u, 3) { |j, i, c| + CvScalar.new(c * 10, c * 20, c * 30) + } + + splitted = image.split + assert_equal(3, splitted.size) + splitted.each_with_index { |img, channel| + assert_equal(IplImage, img.class) + assert_equal(image.height, img.height) + assert_equal(image.width, img.width) + assert_equal(1, img.channel) + + img.height.times { |j| + img.width.times { |i| + val = image[j, i][channel] + assert_cvscalar_equal(CvScalar.new(val), img[j, i]) + } + } + } end def test_merge