1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

add Mat#threshold!

This commit is contained in:
ser1zw 2017-04-30 04:37:45 +09:00
parent 18c3df7871
commit 85e744c07d
4 changed files with 97 additions and 12 deletions

View file

@ -1258,6 +1258,7 @@ namespace rubyopencv {
rb_define_method(rb_klass, "median_blur", RUBY_METHOD_FUNC(rb_median_blur), 1); // in ext/opencv/mat_imgproc.cpp
rb_define_method(rb_klass, "median_blur!", RUBY_METHOD_FUNC(rb_median_blur_bang), 1); // in ext/opencv/mat_imgproc.cpp
rb_define_method(rb_klass, "threshold", RUBY_METHOD_FUNC(rb_threshold), 3); // in ext/opencv/mat_imgproc.cpp
rb_define_method(rb_klass, "threshold!", RUBY_METHOD_FUNC(rb_threshold_bang), 3); // in ext/opencv/mat_imgproc.cpp
rb_define_method(rb_klass, "adaptive_threshold", RUBY_METHOD_FUNC(rb_adaptive_threshold), 5); // in ext/opencv/mat_imgproc.cpp
rb_define_method(rb_klass, "save", RUBY_METHOD_FUNC(rb_save), -1);

View file

@ -452,6 +452,22 @@ namespace rubyopencv {
return self;
}
VALUE rb_threshold_internal(VALUE self, VALUE threshold, VALUE max_value, VALUE threshold_type, VALUE dest) {
cv::Mat* selfptr = obj2mat(self);
cv::Mat* destptr = obj2mat(dest);
int threshold_type_value = NUM2INT(threshold_type);
double optimal_threshold = cv::threshold(*selfptr, *destptr, NUM2DBL(threshold), NUM2DBL(max_value), threshold_type_value);
VALUE ret = Qnil;
if ((threshold_type_value & cv::THRESH_OTSU) || (threshold_type_value & cv::THRESH_TRIANGLE)) {
ret = rb_assoc_new(dest, DBL2NUM(optimal_threshold));
}
else {
ret = dest;
}
return ret;
}
/*
* Applies a fixed-level threshold to each array element.
*
@ -474,27 +490,32 @@ namespace rubyopencv {
* @opencv_func cv::threshold
*/
VALUE rb_threshold(VALUE self, VALUE threshold, VALUE max_value, VALUE threshold_type) {
cv::Mat* selfptr = obj2mat(self);
cv::Mat* dstptr = NULL;
double optimal_threshold = 0.0;
int threshold_type_value = NUM2INT(threshold_type);
cv::Mat* destptr = new cv::Mat();
VALUE dest = mat2obj(destptr);
VALUE ret = Qnil;
try {
dstptr = new cv::Mat();
optimal_threshold = cv::threshold(*selfptr, *dstptr, NUM2DBL(threshold), NUM2DBL(max_value), threshold_type_value);
ret = rb_threshold_internal(self, threshold, max_value, threshold_type, dest);
}
catch (cv::Exception& e) {
delete dstptr;
Error::raise(e);
}
return ret;
}
/*
* @overload threshold!(threshold, max_value, type)
* @see #threshold
*/
VALUE rb_threshold_bang(VALUE self, VALUE threshold, VALUE max_value, VALUE threshold_type) {
VALUE ret = Qnil;
VALUE dst = mat2obj(dstptr, CLASS_OF(self));
if ((threshold_type_value & cv::THRESH_OTSU) || (threshold_type_value & cv::THRESH_TRIANGLE)) {
ret = rb_assoc_new(dst, DBL2NUM(optimal_threshold));
try {
ret = rb_threshold_internal(self, threshold, max_value, threshold_type, self);
}
else {
ret = dst;
catch (cv::Exception& e) {
Error::raise(e);
}
return ret;
}

View file

@ -23,6 +23,7 @@ namespace rubyopencv {
VALUE rb_median_blur(VALUE self, VALUE ksize);
VALUE rb_median_blur_bang(VALUE self, VALUE ksize);
VALUE rb_threshold(VALUE self, VALUE threshold, VALUE max_value, VALUE threshold_type);
VALUE rb_threshold_bang(VALUE self, VALUE threshold, VALUE max_value, VALUE threshold_type);
VALUE rb_adaptive_threshold(VALUE self, VALUE max_value, VALUE adaptive_method,
VALUE threshold_type, VALUE block_size, VALUE delta);
}

View file

@ -605,6 +605,68 @@ class TestCvMat < OpenCVTestCase
# Cv::wait_key
end
def test_threshold_bang
m0 = Cv::Mat.zeros(2, 2, Cv::CV_8U)
m0[0, 0] = Cv::Scalar.new(10)
m0[0, 1] = Cv::Scalar.new(20)
m0[1, 0] = Cv::Scalar.new(30)
m0[1, 1] = Cv::Scalar.new(40)
m = m0.clone
m.threshold!(25, 255, Cv::THRESH_BINARY)
expected = "<Cv::Mat:2x2,depth=0,channels=1,\n[ 0, 0;\n 255, 255]>"
assert_equal(expected, m.to_s)
m = m0.clone
m.threshold!(25, 255, Cv::THRESH_BINARY_INV)
expected = "<Cv::Mat:2x2,depth=0,channels=1,\n[255, 255;\n 0, 0]>"
assert_equal(expected, m.to_s)
m = m0.clone
m.threshold!(25, 255, Cv::THRESH_TRUNC)
expected = "<Cv::Mat:2x2,depth=0,channels=1,\n[ 10, 20;\n 25, 25]>"
assert_equal(expected, m.to_s)
m = m0.clone
m.threshold!(25, 255, Cv::THRESH_TOZERO)
expected = "<Cv::Mat:2x2,depth=0,channels=1,\n[ 0, 0;\n 30, 40]>"
assert_equal(expected, m.to_s)
m = m0.clone
m.threshold!(25, 255, Cv::THRESH_TOZERO_INV)
expected = "<Cv::Mat:2x2,depth=0,channels=1,\n[ 10, 20;\n 0, 0]>"
assert_equal(expected, m.to_s)
m = m0.clone
_, optimal_threshold = m.threshold!(25, 255, Cv::THRESH_BINARY | Cv::THRESH_OTSU)
expected = "<Cv::Mat:2x2,depth=0,channels=1,\n[ 0, 0;\n 255, 255]>"
assert_equal(expected, m.to_s)
assert_in_delta(20, optimal_threshold, 0.1)
m = m0.clone
_, optimal_threshold = m.threshold!(25, 255, Cv::THRESH_BINARY | Cv::THRESH_TRIANGLE)
expected = "<Cv::Mat:2x2,depth=0,channels=1,\n[ 0, 255;\n 255, 255]>"
assert_equal(expected, m.to_s)
assert_in_delta(12, optimal_threshold, 0.1)
assert_raise(TypeError) {
m0.threshold!(DUMMY_OBJ, 255, Cv::THRESH_BINARY)
}
assert_raise(TypeError) {
m0.threshold!(25, DUMMY_OBJ, Cv::THRESH_BINARY)
}
assert_raise(TypeError) {
m0.threshold!(25, 255, DUMMY_OBJ)
}
# m0 = Cv::imread(FILENAME_LENA256x256, 0)
# m = m0.clone
# m.threshold!(127, 255, Cv::THRESH_BINARY)
# w = Window.new('Original | Binary')
# w.show(Cv::hconcat([m0, m]))
# Cv::wait_key
end
def test_adaptive_threshold
m0 = Cv::Mat.new(2, 2, Cv::CV_8U)
m0[0, 0] = Cv::Scalar.new(10)