add CvMat#norm

This commit is contained in:
ser1zw 2015-01-02 03:12:52 +09:00
parent 32ff552078
commit 197d5b92fd
3 changed files with 76 additions and 1 deletions

View File

@ -2276,6 +2276,47 @@ rb_min_max_loc(int argc, VALUE *argv, VALUE self)
return rb_ary_new3(4, rb_float_new(min_val), rb_float_new(max_val), min_loc, max_loc);
}
/*
* Calculates an absolute array norm, an absolute difference norm, or a relative difference norm.
*
* @overload norm(src1, src2=nil, norm_type=NORM_L2, mask=nil)
* @param src1 [CvMat] First input array.
* @param src2 [CvMat] Second input array of the same size and the same type as <tt>src1</tt>.
* @param norm_type [Integer] Type of the norm.
* @param mask [CvMat] Optional operation mask; it must have the same size as <tt>src1</tt> and <tt>CV_8UC1</tt> type.
* @return [Number] The norm of two arrays.
* @opencv_func cvNorm
* @scope class
*/
VALUE
rb_norm(int argc, VALUE *argv, VALUE self)
{
VALUE src1, src2, norm_type_val, mask_val;
rb_scan_args(argc, argv, "13", &src1, &src2, &norm_type_val, &mask_val);
CvMat *src1_ptr = NULL;
CvMat *src2_ptr = NULL;
int norm_type = NIL_P(norm_type_val) ? cv::NORM_L2 : NUM2INT(norm_type_val);
CvMat *mask = NULL;
double norm = 0.0;
try {
src1_ptr = CVMAT_WITH_CHECK(src1);
if (!NIL_P(src2)) {
src2_ptr = CVMAT_WITH_CHECK(src2);
}
if (!NIL_P(mask_val)) {
mask = CVMAT_WITH_CHECK(mask_val);
}
norm = cvNorm(src1_ptr, src2_ptr, norm_type, mask);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return DBL2NUM(norm);
}
/*
* Calculates the dot product of two arrays in Euclidean metrics.
*
@ -5913,6 +5954,7 @@ init_ruby_class()
rb_define_method(rb_klass, "avg_sdv", RUBY_METHOD_FUNC(rb_avg_sdv), -1);
rb_define_method(rb_klass, "sdv", RUBY_METHOD_FUNC(rb_sdv), -1);
rb_define_method(rb_klass, "min_max_loc", RUBY_METHOD_FUNC(rb_min_max_loc), -1);
rb_define_singleton_method(rb_klass, "norm", RUBY_METHOD_FUNC(rb_norm), -1);
rb_define_method(rb_klass, "dot_product", RUBY_METHOD_FUNC(rb_dot_product), 1);
rb_define_method(rb_klass, "cross_product", RUBY_METHOD_FUNC(rb_cross_product), 1);
rb_define_method(rb_klass, "transform", RUBY_METHOD_FUNC(rb_transform), -1);

View File

@ -119,7 +119,7 @@ VALUE rb_avg_sdv(int argc, VALUE *argv, VALUE self);
VALUE rb_sdv(int argc, VALUE *argv, VALUE self);
VALUE rb_min_max_loc(int argc, VALUE *argv, VALUE self);
//VALUE rb_norm();
VALUE rb_norm(int argc, VALUE *argv, VALUE self);
VALUE rb_dot_product(VALUE self, VALUE mat);
VALUE rb_cross_product(VALUE self, VALUE mat);
// VALUE rb_gemm();

View File

@ -2161,6 +2161,39 @@ class TestCvMat < OpenCVTestCase
}
end
def test_norm
src1 = CvMat.new(3, 3, :cv32f, 1).set_data([1, 2, 3, 4, 5, 6, 7, 8, 9])
src2 = CvMat.new(3, 3, :cv32f, 1).set_data([2, 3, 4, 5, 6, 7, 8, 9, 1])
mask = CvMat.new(3, 3, :cv8u, 1).set_data([1, 1, 0, 1, 1, 0, 0, 0, 0])
assert_in_delta(CvMat.norm(src1), 16.88, 0.01)
assert_in_delta(CvMat.norm(src1, nil, CV_NORM_L1), 45.0, 0.01)
assert_in_delta(CvMat.norm(src1, nil, CV_NORM_L2), 16.88, 0.01)
assert_in_delta(CvMat.norm(src1, nil, CV_NORM_INF), 9.0, 0.01)
assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L1), 16.0, 0.01)
assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L2), 8.49, 0.01)
assert_in_delta(CvMat.norm(src1, src2, CV_NORM_INF), 8.0, 0.01)
assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L1, mask), 4.0, 0.01)
assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L2, mask), 2.0, 0.01)
assert_in_delta(CvMat.norm(src1, src2, CV_NORM_INF, mask), 1.0, 0.01)
assert_raise(TypeError) {
CvMat.norm(DUMMY_OBJ)
}
assert_raise(TypeError) {
CvMat.norm(src1, DUMMY_OBJ)
}
assert_raise(TypeError) {
CvMat.norm(src1, src2, DUMMY_OBJ)
}
assert_raise(TypeError) {
CvMat.norm(src1, src2, CV_NORM_L1, DUMMY_OBJ)
}
end
def test_dot_product
m1 = create_cvmat(2, 2, :cv32f, 1) { |j, i, c|
CvScalar.new(c * 0.5)