diff --git a/ext/opencv/mat.cpp b/ext/opencv/mat.cpp index e3f60cc..409a879 100644 --- a/ext/opencv/mat.cpp +++ b/ext/opencv/mat.cpp @@ -824,6 +824,42 @@ namespace rubyopencv { return mat2obj(retptr, CLASS_OF(self)); } + /* + * Calculates the per-element absolute difference between two + * or between an array and a scalar. + * + * @overload absdiff(other) + * @param other [Mat, Scalar] Input array or scalar + * @return [Mat] Output array that has the same size and type as input arrays. + * @opencv_func cv::absdiff + */ + VALUE rb_absdiff(VALUE self, VALUE other) { + cv::Mat* selfptr = obj2mat(self); + cv::Mat* retptr = NULL; + + try { + retptr = new cv::Mat(); + if (rb_obj_is_kind_of(other, rb_klass)) { + cv::Mat* tmp = obj2mat(other); + cv::absdiff(*selfptr, *tmp, *retptr); + } + else if (rb_obj_is_kind_of(other, Scalar::klass())) { + cv::Scalar* tmp = Scalar::obj2scalar(other); + cv::absdiff(*selfptr, *tmp, *retptr); + } + else { + rb_raise(rb_eTypeError, "no implicit conversion of %s into Cv::Mat or Cv::Scalar", + rb_obj_classname(other)); + } + } + catch (cv::Exception& e) { + Error::raise(e); + delete retptr; + } + + return mat2obj(retptr, CLASS_OF(self)); + } + /* * Extracts a diagonal from a matrix. * @@ -1171,6 +1207,7 @@ namespace rubyopencv { rb_define_alias(rb_klass, "^", "bitwise_xor"); rb_define_method(rb_klass, "bitwise_not", RUBY_METHOD_FUNC(rb_bitwise_not), -1); rb_define_alias(rb_klass, "~", "bitwise_not"); + rb_define_method(rb_klass, "absdiff", RUBY_METHOD_FUNC(rb_absdiff), 1); rb_define_method(rb_klass, "diag", RUBY_METHOD_FUNC(rb_diag), -1); rb_define_method(rb_klass, "dot", RUBY_METHOD_FUNC(rb_dot), 1); rb_define_method(rb_klass, "cross", RUBY_METHOD_FUNC(rb_cross), 1); diff --git a/test/test_mat.rb b/test/test_mat.rb index 6cf5001..5e2a957 100755 --- a/test/test_mat.rb +++ b/test/test_mat.rb @@ -454,6 +454,32 @@ class TestMat < OpenCVTestCase } end + def test_absdiff + m0 = Mat.ones(3, 3, CV_8U) * 3 + m1 = Mat.ones(3, 3, CV_8U) * 4 + s1 = Scalar.new(4) + + m1 = m0.absdiff(m1) + m2 = m0.absdiff(s1) + + [m1, m2].each { |m| + assert_equal(m0.class, m.class) + assert_equal(m0.rows, m.rows) + assert_equal(m0.cols, m.cols) + assert_equal(m0.depth, m.depth) + assert_equal(m0.channels, m.channels) + m.rows.times { |r| + m.cols.times { |c| + assert_equal(1, m[r, c][0]) + } + } + } + + assert_raise(TypeError) { + m0.absdiff(DUMMY_OBJ) + } + end + def test_resize m0 = Mat.ones(200, 300, CV_8U) s = Size.new(150, 100)