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

add CvMat#adaptive_threshold

This commit is contained in:
ser1zw 2012-02-15 02:11:41 +09:00
parent 86b5d1918b
commit 71b2743c76
4 changed files with 135 additions and 0 deletions

View file

@ -338,6 +338,7 @@ void define_ruby_class()
rb_define_method(rb_klass, "filter2d", RUBY_METHOD_FUNC(rb_filter2d), -1);
rb_define_method(rb_klass, "integral", RUBY_METHOD_FUNC(rb_integral), -1);
rb_define_method(rb_klass, "threshold", RUBY_METHOD_FUNC(rb_threshold), -1);
rb_define_method(rb_klass, "adaptive_threshold", RUBY_METHOD_FUNC(rb_adaptive_threshold), -1);
rb_define_method(rb_klass, "pyr_down", RUBY_METHOD_FUNC(rb_pyr_down), -1);
rb_define_method(rb_klass, "pyr_up", RUBY_METHOD_FUNC(rb_pyr_up), -1);
@ -4418,6 +4419,60 @@ rb_threshold(int argc, VALUE *argv, VALUE self)
return rb_threshold_internal(type, threshold, max_value, use_otsu, self);
}
/*
* call-seq:
* adaptive_threshold(max_value[, options]) -> cvmat
*
* Applies an adaptive threshold to an array.
*
* ==== params:
*
* * <b>max_value (Number)</b> - Maximum value that is used with +CV_THRESH_BINARY+ and +CV_THRESH_BINARY_INV+
* * <b>options (Hash)</b> - threshold option
* * <b>:threshold_type (Integer or Symbol)</b> - Thresholding type; must be one of +CV_THRESH_BINARY+ or +:binary+, +CV_THRESH_BINARY_INV+ or +:binary_inv+ (default: +CV_THRESH_BINARY+)
* * <b>:adaptive_method (Integer or Symbol)</b> - Adaptive thresholding algorithm to use: +CV_ADAPTIVE_THRESH_MEAN_C+ or +:mean_c+, +CV_ADAPTIVE_THRESH_GAUSSIAN_C+ or +:gaussian_c+ (default: +CV_ADAPTIVE_THRESH_MEAN_C+)
* * <b>:block_size (Integer)</b> - The size of a pixel neighborhood that is used to calculate a threshold value for the pixel: 3, 5, 7, and so on (default: 3)
* * <b>:param1 (Number)</b> - The method-dependent parameter. For the methods +CV_ADAPTIVE_THRESH_MEAN_C+ and +CV_ADAPTIVE_THRESH_GAUSSIAN_C+ it is a constant subtracted from the mean or weighted mean, though it may be negative (default: 5)
*/
VALUE
rb_adaptive_threshold(int argc, VALUE *argv, VALUE self)
{
VALUE max_value, options;
rb_scan_args(argc, argv, "11", &max_value, &options);
int threshold_type = CV_THRESH_BINARY;
int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C;
int block_size = 3;
double param1 = 5;
if (!NIL_P(options)) {
Check_Type(options, T_HASH);
threshold_type = CVMETHOD("THRESHOLD_TYPE", LOOKUP_CVMETHOD(options, "threshold_type"),
CV_THRESH_BINARY);
adaptive_method = CVMETHOD("ADAPTIVE_METHOD", LOOKUP_CVMETHOD(options, "adaptive_method"),
CV_ADAPTIVE_THRESH_MEAN_C);
VALUE _block_size = LOOKUP_CVMETHOD(options, "block_size");
if (!NIL_P(_block_size)) {
block_size = NUM2INT(_block_size);
}
VALUE _param1 = LOOKUP_CVMETHOD(options, "param1");
if (!NIL_P(_param1)) {
param1 = NUM2INT(_param1);
}
}
CvArr* self_ptr = CVARR(self);
VALUE dst = new_mat_kind_object(cvGetSize(self_ptr), self);
try {
cvAdaptiveThreshold(self_ptr, CVARR(dst), NUM2DBL(max_value), adaptive_method, threshold_type,
block_size, param1);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return dst;
}
/*
* call-seq:
* pyr_down(<i>[filter = :gaussian_5x5]</i>) -> cvmat

View file

@ -216,6 +216,10 @@ define_ruby_module()
rb_define_const(rb_module, "CV_THRESH_TOZERO_INV", INT2FIX(CV_THRESH_TOZERO_INV));
rb_define_const(rb_module, "CV_THRESH_OTSU", INT2FIX(CV_THRESH_OTSU));
/* Adaptive methods */
rb_define_const(rb_module, "CV_ADAPTIVE_THRESH_MEAN_C", INT2FIX(CV_ADAPTIVE_THRESH_MEAN_C));
rb_define_const(rb_module, "CV_ADAPTIVE_THRESH_GAUSSIAN_C", INT2FIX(CV_ADAPTIVE_THRESH_GAUSSIAN_C));
/* Border type */
rb_define_const(rb_module, "IPL_BORDER_CONSTANT", INT2FIX(IPL_BORDER_CONSTANT));
rb_define_const(rb_module, "IPL_BORDER_REPLICATE", INT2FIX(IPL_BORDER_REPLICATE));
@ -413,6 +417,12 @@ define_ruby_module()
REGISTER_CVMETHOD(smoothing_type, "median", CV_MEDIAN);
REGISTER_CVMETHOD(smoothing_type, "bilateral", CV_BILATERAL);
VALUE adaptive_method = rb_hash_new();
/* {:mean_c, :gaussian_c}: Adaptive thresholding algorithm */
rb_define_const(rb_module, "ADAPTIVE_METHOD", adaptive_method);
REGISTER_CVMETHOD(adaptive_method, "mean_c", CV_ADAPTIVE_THRESH_MEAN_C);
REGISTER_CVMETHOD(adaptive_method, "gaussian_c", CV_ADAPTIVE_THRESH_GAUSSIAN_C);
VALUE threshold_type = rb_hash_new();
/* {:binary, :binary_inv, :trunc, :tozero, :tozero_inv, :otsu} : Thresholding types */
rb_define_const(rb_module, "THRESHOLD_TYPE", threshold_type);

View file

@ -983,6 +983,72 @@ class TestCvMat_imageprocessing < OpenCVTestCase
mat0.threshold(1, 2, :binary, DUMMY_OBJ)
end
def test_adaptive_threshold
mat0 = create_cvmat(5, 5, :cv8u, 1) { |j, i, c| (c + 1) * 10 }
mat1 = mat0.adaptive_threshold(128)
expected1 = [0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]
expected1.each_with_index { |expected, i|
assert_equal(expected, mat1[i][0])
}
mat2a = mat0.adaptive_threshold(255, :adaptive_method => :mean_c,
:threshold_type => :binary, :block_size => 5,
:param1 => 10)
mat2b = mat0.adaptive_threshold(255, :adaptive_method => CV_THRESH_BINARY,
:threshold_type => CV_ADAPTIVE_THRESH_MEAN_C, :block_size => 5,
:param1 => 10)
expected2 = [0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255]
[mat2a, mat2b].each { |mat2|
assert_equal(CvMat, mat2.class)
assert_equal(mat0.rows, mat2.rows)
assert_equal(mat0.cols, mat2.cols)
assert_equal(mat0.depth, mat2.depth)
assert_equal(mat0.channel, mat2.channel)
expected2.each_with_index { |expected, i|
assert_equal(expected, mat2[i][0])
}
}
mat3a = mat0.adaptive_threshold(255, :adaptive_method => :gaussian_c,
:threshold_type => :binary_inv, :block_size => 5,
:param1 => 10)
mat3b = mat0.adaptive_threshold(255, :adaptive_method => CV_ADAPTIVE_THRESH_GAUSSIAN_C,
:threshold_type => CV_THRESH_BINARY_INV, :block_size => 5,
:param1 => 10)
expected3 = [255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[mat3a, mat3b].each { |mat3|
assert_equal(CvMat, mat3.class)
assert_equal(mat0.rows, mat3.rows)
assert_equal(mat0.cols, mat3.cols)
assert_equal(mat0.depth, mat3.depth)
assert_equal(mat0.channel, mat3.channel)
expected3.each_with_index { |expected, i|
assert_equal(expected, mat3[i][0])
}
}
assert_raise(TypeError) {
mat0.adaptive_threshold(DUMMY_OBJ)
}
assert_raise(TypeError) {
mat0.adaptive_threshold(0, DUMMY_OBJ)
}
assert_raise(TypeError) {
mat0.adaptive_threshold(0, :adaptive_method => DUMMY_OBJ)
}
assert_raise(TypeError) {
mat0.adaptive_threshold(0, :threshold_type => DUMMY_OBJ)
}
assert_raise(TypeError) {
mat0.adaptive_threshold(0, :block_size => DUMMY_OBJ)
}
assert_raise(TypeError) {
mat0.adaptive_threshold(0, :param1 => DUMMY_OBJ)
}
end
def test_pyr_down
mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH)
mat1 = mat0.pyr_down

View file

@ -62,6 +62,10 @@ class TestOpenCV < OpenCVTestCase
assert_equal(4, CV_THRESH_TOZERO_INV)
assert_equal(8, CV_THRESH_OTSU)
# Adaptive methods
assert_equal(0, CV_ADAPTIVE_THRESH_MEAN_C)
assert_equal(1, CV_ADAPTIVE_THRESH_GAUSSIAN_C)
# Retrieval mode
assert_equal(0, CV_RETR_EXTERNAL)
assert_equal(1, CV_RETR_LIST)