diff --git a/ext/opencv/mat.cpp b/ext/opencv/mat.cpp index da0da4b..bd2eb69 100644 --- a/ext/opencv/mat.cpp +++ b/ext/opencv/mat.cpp @@ -1247,6 +1247,7 @@ namespace rubyopencv { rb_define_method(rb_klass, "rectangle!", RUBY_METHOD_FUNC(rb_rectangle_bang), -1); // in ext/opencv/mat_drawing.cpp rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1); // in ext/opencv/mat_imgproc.cpp + rb_define_method(rb_klass, "resize!", RUBY_METHOD_FUNC(rb_resize_bang), -1); // in ext/opencv/mat_imgproc.cpp rb_define_method(rb_klass, "cvt_color", RUBY_METHOD_FUNC(rb_cvt_color), -1); // in ext/opencv/mat_imgproc.cpp rb_define_method(rb_klass, "blur", RUBY_METHOD_FUNC(rb_blur), -1); // in ext/opencv/mat_imgproc.cpp rb_define_method(rb_klass, "gaussian_blur", RUBY_METHOD_FUNC(rb_gaussian_blur), -1); // in ext/opencv/mat_imgproc.cpp diff --git a/ext/opencv/mat_imgproc.cpp b/ext/opencv/mat_imgproc.cpp index 249561b..d51971e 100644 --- a/ext/opencv/mat_imgproc.cpp +++ b/ext/opencv/mat_imgproc.cpp @@ -186,6 +186,20 @@ namespace rubyopencv { return mat2obj(destptr, CLASS_OF(self)); } + cv::Mat* rb_resize_internal(int argc, VALUE *argv, VALUE self, cv::Mat* destptr) { + VALUE size, inv_scale_x, inv_scale_y, interpolation; + rb_scan_args(argc, argv, "13", &size, &inv_scale_x, &inv_scale_y, &interpolation); + cv::Size* sizeptr = Size::obj2size(size); + cv::Mat* selfptr = obj2mat(self); + double sx = NIL_P(inv_scale_x) ? 0 : NUM2DBL(inv_scale_x); + double sy = NIL_P(inv_scale_y) ? 0 : NUM2DBL(inv_scale_y); + int method = NIL_P(interpolation) ? CV_INTER_LINEAR : NUM2INT(interpolation); + + cv::resize(*selfptr, *destptr, *sizeptr, sx, sy, method); + + return destptr; + } + /* * Resizes an image. * @@ -203,17 +217,9 @@ namespace rubyopencv { * @opencv_func cv::Resize */ VALUE rb_resize(int argc, VALUE *argv, VALUE self) { - VALUE size, inv_scale_x, inv_scale_y, interpolation; - rb_scan_args(argc, argv, "13", &size, &inv_scale_x, &inv_scale_y, &interpolation); - cv::Size* sizeptr = Size::obj2size(size); - cv::Mat* selfptr = obj2mat(self); cv::Mat* destptr = new cv::Mat(); - double sx = NIL_P(inv_scale_x) ? 0 : NUM2DBL(inv_scale_x); - double sy = NIL_P(inv_scale_y) ? 0 : NUM2DBL(inv_scale_y); - int method = NIL_P(interpolation) ? CV_INTER_LINEAR : NUM2INT(interpolation); - try { - cv::resize(*selfptr, *destptr, *sizeptr, sx, sy, method); + rb_resize_internal(argc, argv, self, destptr); } catch (cv::Exception& e) { delete destptr; @@ -223,6 +229,34 @@ namespace rubyopencv { return mat2obj(destptr, CLASS_OF(self)); } + /* + * Resizes an image. + * + * @overload resize(size, interpolation = INTER_LINEAR) + * @param size [Size] Output image size. + * @param interpolation [Integer] Interpolation method: + * * INTER_NEAREST - A nearest-neighbor interpolation + * * INTER_LINEAR - A bilinear interpolation (used by default) + * * INTER_AREA - Resampling using pixel area relation. It may be a preferred method for + * image decimation, as it gives moire'-free results. But when the image is zoomed, + * it is similar to the INTER_NEAREST method. + * * INTER_CUBIC - A bicubic interpolation over 4x4 pixel neighborhood + * * INTER_LANCZOS4 - A Lanczos interpolation over 8x8 pixel neighborhood + * @return [Mat] Output image. + * @opencv_func cv::Resize + */ + VALUE rb_resize_bang(int argc, VALUE *argv, VALUE self) { + cv::Mat* destptr = obj2mat(self); + try { + rb_resize_internal(argc, argv, self, destptr); + } + catch (cv::Exception& e) { + Error::raise(e); + } + + return self; + } + /* * Blurs an image using the normalized box filter. * diff --git a/ext/opencv/mat_imgproc.hpp b/ext/opencv/mat_imgproc.hpp index 5583f97..58c01d5 100644 --- a/ext/opencv/mat_imgproc.hpp +++ b/ext/opencv/mat_imgproc.hpp @@ -13,6 +13,7 @@ namespace rubyopencv { VALUE rb_laplacian(int argc, VALUE *argv, VALUE self); VALUE rb_cvt_color(int argc, VALUE *argv, VALUE self); VALUE rb_resize(int argc, VALUE *argv, VALUE self); + VALUE rb_resize_bang(int argc, VALUE *argv, VALUE self); VALUE rb_blur(int argc, VALUE *argv, VALUE self); VALUE rb_gaussian_blur(int argc, VALUE *argv, VALUE self); VALUE rb_median_blur(VALUE self, VALUE ksize); diff --git a/test/test_mat.rb b/test/test_mat.rb index 5e2a957..c86cf0c 100755 --- a/test/test_mat.rb +++ b/test/test_mat.rb @@ -480,32 +480,6 @@ class TestMat < OpenCVTestCase } end - def test_resize - m0 = Mat.ones(200, 300, CV_8U) - s = Size.new(150, 100) - - m = m0.resize(s) - assert_equal(s.height, m.rows) - assert_equal(s.width, m.cols) - assert_equal(m0.depth, m.depth) - assert_equal(m0.dims, m.dims) - assert_equal(m0.channels, m.channels) - - [INTER_NEAREST, INTER_LINEAR, INTER_AREA, - INTER_CUBIC, INTER_LANCZOS4].each { |interpolation| - m = m0.resize(s, interpolation) - assert_equal(s.height, m.rows) - assert_equal(s.width, m.cols) - assert_equal(m0.depth, m.depth) - assert_equal(m0.dims, m.dims) - assert_equal(m0.channels, m.channels) - } - - assert_raise(TypeError) { - m.resize(DUMMY_OBJ) - } - end - def test_diag m0 = Mat.new(3, 3, CV_8U) i = 1 diff --git a/test/test_mat_imgproc.rb b/test/test_mat_imgproc.rb index 644b6cb..209fddf 100755 --- a/test/test_mat_imgproc.rb +++ b/test/test_mat_imgproc.rb @@ -6,6 +6,60 @@ require File.expand_path(File.dirname(__FILE__)) + '/helper' include Cv class TestCvMat < OpenCVTestCase + def test_resize + m0 = Mat.ones(200, 300, CV_8U) + s = Size.new(150, 100) + + m = m0.resize(s) + assert_equal(s.height, m.rows) + assert_equal(s.width, m.cols) + assert_equal(m0.depth, m.depth) + assert_equal(m0.dims, m.dims) + assert_equal(m0.channels, m.channels) + + [INTER_NEAREST, INTER_LINEAR, INTER_AREA, + INTER_CUBIC, INTER_LANCZOS4].each { |interpolation| + m = m0.resize(s, interpolation) + assert_equal(s.height, m.rows) + assert_equal(s.width, m.cols) + assert_equal(m0.depth, m.depth) + assert_equal(m0.dims, m.dims) + assert_equal(m0.channels, m.channels) + } + + assert_raise(TypeError) { + m.resize(DUMMY_OBJ) + } + end + + def test_resize_bang + m0 = Mat.ones(200, 300, CV_8U) + m = m0.clone + s = Size.new(150, 100) + + m.resize!(s) + assert_equal(s.height, m.rows) + assert_equal(s.width, m.cols) + assert_equal(m0.depth, m.depth) + assert_equal(m0.dims, m.dims) + assert_equal(m0.channels, m.channels) + + [INTER_NEAREST, INTER_LINEAR, INTER_AREA, + INTER_CUBIC, INTER_LANCZOS4].each { |interpolation| + m = m0.clone + m.resize!(s, interpolation) + assert_equal(s.height, m.rows) + assert_equal(s.width, m.cols) + assert_equal(m0.depth, m.depth) + assert_equal(m0.dims, m.dims) + assert_equal(m0.channels, m.channels) + } + + assert_raise(TypeError) { + m.resize!(DUMMY_OBJ) + } + end + def test_sobel m0 = Cv::imread(FILENAME_LENA256x256, 0)