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

add CvChain#approx_chains

This commit is contained in:
ser1zw 2012-05-01 05:19:58 +09:00
parent c28379c393
commit 720c7c9448
3 changed files with 65 additions and 17 deletions

View file

@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVCHAIN
#define APPROX_CHAIN_OPTION(op) rb_get_option_table(rb_klass, "APPROX_CHAIN_OPTION", op) #define APPROX_CHAIN_OPTION(op) rb_get_option_table(rb_klass, "APPROX_CHAIN_OPTION", op)
#define APPROX_CHAIN_METHOD(op) CVMETHOD("APPROX_CHAIN_METHOD", LOOKUP_CVMETHOD(op, "method"), CV_CHAIN_APPROX_SIMPLE) #define APPROX_CHAIN_METHOD(op) CVMETHOD("APPROX_CHAIN_METHOD", LOOKUP_CVMETHOD(op, "method"), CV_CHAIN_APPROX_SIMPLE)
#define APPROX_CHAIN_PARAMETER(op) NUM2INT(LOOKUP_CVMETHOD(op, "parameter")) #define APPROX_CHAIN_PARAMETER(op) NUM2INT(LOOKUP_CVMETHOD(op, "parameter"))
#define APPROX_CHAIN_MINIMAL_PARAMETER(op) NUM2INT(LOOKUP_CVMETHOD(op, "minimal_parameter")) #define APPROX_CHAIN_MINIMAL_PERIMETER(op) NUM2INT(LOOKUP_CVMETHOD(op, "minimal_perimeter"))
#define APPROX_CHAIN_RECURSIVE(op) TRUE_OR_FALSE(LOOKUP_CVMETHOD(op, "recursive")) #define APPROX_CHAIN_RECURSIVE(op) TRUE_OR_FALSE(LOOKUP_CVMETHOD(op, "recursive"))
VALUE rb_klass; VALUE rb_klass;
@ -52,7 +52,7 @@ define_ruby_class()
rb_define_const(rb_klass, "APPROX_CHAIN_OPTION", approx_chain_option); rb_define_const(rb_klass, "APPROX_CHAIN_OPTION", approx_chain_option);
rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("method")), ID2SYM(rb_intern("approx_simple"))); rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("method")), ID2SYM(rb_intern("approx_simple")));
rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("parameter")), rb_float_new(0)); rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("parameter")), rb_float_new(0));
rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("minimal_parameter")), INT2FIX(0)); rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("minimal_perimeter")), INT2FIX(0));
rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("recursive")), Qfalse); rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("recursive")), Qfalse);
rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
@ -60,8 +60,8 @@ define_ruby_class()
rb_define_method(rb_klass, "origin=", RUBY_METHOD_FUNC(rb_set_origin), 1); rb_define_method(rb_klass, "origin=", RUBY_METHOD_FUNC(rb_set_origin), 1);
rb_define_method(rb_klass, "codes", RUBY_METHOD_FUNC(rb_codes), 0); rb_define_method(rb_klass, "codes", RUBY_METHOD_FUNC(rb_codes), 0);
rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0); rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0);
rb_define_method(rb_klass, "approx_chain", RUBY_METHOD_FUNC(rb_approx_chain), -1); rb_define_method(rb_klass, "approx_chains", RUBY_METHOD_FUNC(rb_approx_chains), -1);
rb_define_alias(rb_klass, "approx", "approx_chain"); rb_define_alias(rb_klass, "approx", "approx_chains");
} }
VALUE VALUE
@ -172,7 +172,7 @@ rb_points(VALUE self)
/* /*
* call-seq: * call-seq:
* approx_chain(<i>[approx_chain_option]</i>) -> cvcontour * approx_chains(<i>[approx_chain_option]</i>) -> cvcontour
* *
* Approximates Freeman chain(s) with polygonal curve. * Approximates Freeman chain(s) with polygonal curve.
* <i>approx_chain_option</i> should be Hash include these keys. * <i>approx_chain_option</i> should be Hash include these keys.
@ -193,21 +193,22 @@ rb_points(VALUE self)
* *
*/ */
VALUE VALUE
rb_approx_chain(int argc, VALUE *argv, VALUE self) rb_approx_chains(int argc, VALUE *argv, VALUE self)
{ {
VALUE approx_chain_option, storage; VALUE approx_chain_option;
rb_scan_args(argc, argv, "01", &approx_chain_option); rb_scan_args(argc, argv, "01", &approx_chain_option);
approx_chain_option = APPROX_CHAIN_OPTION(approx_chain_option); approx_chain_option = APPROX_CHAIN_OPTION(approx_chain_option);
/* can't compile VC VALUE storage = cCvMemStorage::new_object();
storage = cCvMemStorage::new_object();
CvSeq *seq = cvApproxChains(CVSEQ(self), CVMEMSTORAGE(storage), CvSeq *seq = cvApproxChains(CVSEQ(self), CVMEMSTORAGE(storage),
APPROX_CHAIN_METHOD(approx_chain_option), APPROX_CHAIN_METHOD(approx_chain_option),
APPROX_CHAIN_PARAMETER(approx_chain_option), APPROX_CHAIN_PARAMETER(approx_chain_option),
APPROX_CHAIN_MINIMAL_PARAMETER(approx_chain_option), APPROX_CHAIN_MINIMAL_PERIMETER(approx_chain_option),
APPROX_CHAIN_RECURSIVE(approx_chain_option)); APPROX_CHAIN_RECURSIVE(approx_chain_option));
return cCvSeq::new_sequence(cCvContour::rb_class(), seq, cCvPoint::rb_class(), storage); if (seq && seq->total > 0) {
*/ return cCvSeq::new_sequence(cCvChain::rb_class(), seq, cCvPoint::rb_class(), storage);
}
return Qnil; return Qnil;
} }

View file

@ -28,7 +28,7 @@ VALUE rb_origin(VALUE self);
VALUE rb_set_origin(VALUE self, VALUE origin); VALUE rb_set_origin(VALUE self, VALUE origin);
VALUE rb_codes(VALUE self); VALUE rb_codes(VALUE self);
VALUE rb_points(VALUE self); VALUE rb_points(VALUE self);
VALUE rb_approx_chain(int argc, VALUE *argv, VALUE self); VALUE rb_approx_chains(int argc, VALUE *argv, VALUE self);
VALUE new_object(); VALUE new_object();

View file

@ -54,8 +54,55 @@ class TestCvChain < OpenCVTestCase
assert(chain.points.all? { |a| a.class == CvPoint }) assert(chain.points.all? { |a| a.class == CvPoint })
end end
def test_approx_chain def test_approx_chains
flunk('FIXME: CvChain#approx_chain is not implemented yet.') mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i|
(j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black
}
chain = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_CODE)
contours = chain.approx_chains
assert_equal(CvChain, contours.class)
assert(contours.size > 0)
assert(contours.all? { |c| c.class == CvPoint })
[CV_CHAIN_APPROX_NONE, CV_CHAIN_APPROX_SIMPLE,
CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS,
:approx_none, :approx_simple, :approx_tc89_l1, :approx_tc89_kcos].each { |method|
contours = chain.approx_chains(:method => method)
assert_equal(CvChain, contours.class)
assert(contours.size > 0)
assert(contours.all? { |c| c.class == CvPoint })
}
contours = chain.approx_chains(:minimal_parameter => 10)
assert_equal(CvChain, contours.class)
assert(contours.size > 0)
assert(contours.all? { |c| c.class == CvPoint })
contours = chain.approx_chains(:minimal_perimeter => (32 * 2 * Math::PI).ceil)
assert_nil(contours)
[true, false].each { |recursive|
contours = chain.approx_chains(:recursive => recursive)
assert_equal(CvChain, contours.class)
assert(contours.size > 0)
assert(contours.all? { |c| c.class == CvPoint })
}
contours = chain.approx_chains(:method => :approx_simple,
:minimal_parameter => 100, :recursive => false)
assert_equal(CvChain, contours.class)
assert(contours.size > 0)
assert(contours.all? { |c| c.class == CvPoint })
# Uncomment the following lines to show the result
# contours = chain.approx_chains
# dst = mat0.clone.zero
# begin
# dst.draw_contours!(contours, CvColor::White, CvColor::Black, 2,
# :thickness => 1, :line_type => :aa)
# end while (contours = contours.h_next)
# snap dst
end end
end end