mirror of
https://github.com/ruby-opencv/ruby-opencv
synced 2023-03-27 23:22:12 -04:00
implemented CvMat#extract_surf
This commit is contained in:
parent
3c23c44edc
commit
041f9cc89f
3 changed files with 133 additions and 1 deletions
|
@ -406,6 +406,8 @@ void define_ruby_class()
|
||||||
rb_define_singleton_method(rb_klass, "compute_correspond_epilines",
|
rb_define_singleton_method(rb_klass, "compute_correspond_epilines",
|
||||||
RUBY_METHOD_FUNC(rb_compute_correspond_epilines), 3);
|
RUBY_METHOD_FUNC(rb_compute_correspond_epilines), 3);
|
||||||
|
|
||||||
|
rb_define_method(rb_klass, "extract_surf", RUBY_METHOD_FUNC(rb_extract_surf), -1);
|
||||||
|
|
||||||
rb_define_method(rb_klass, "save_image", RUBY_METHOD_FUNC(rb_save_image), 1);
|
rb_define_method(rb_klass, "save_image", RUBY_METHOD_FUNC(rb_save_image), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5251,6 +5253,75 @@ rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_image, VAL
|
||||||
return correspondent_lines;
|
return correspondent_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* extract_surf(params[,mask,keypoints]) -> [cvseq(cvsurfpoint), array(float)]
|
||||||
|
* Extracts Speeded Up Robust Features from an image
|
||||||
|
*
|
||||||
|
* <i>params</i> (CvSURFParams) - Various algorithm parameters put to the structure CvSURFParams.
|
||||||
|
* <i>mask</i> (CvMat) - The optional input 8-bit mask. The features are only found in the areas that contain more than 50% of non-zero mask pixels.
|
||||||
|
* <i>keypoints</i> (CvSeq which includes CvSURFPoint) - Provided keypoints
|
||||||
|
*/
|
||||||
|
VALUE
|
||||||
|
rb_extract_surf(int argc, VALUE *argv, VALUE self)
|
||||||
|
{
|
||||||
|
VALUE _params, _mask, _keypoints;
|
||||||
|
rb_scan_args(argc, argv, "12", &_params, &_mask, &_keypoints);
|
||||||
|
|
||||||
|
// Prepare arguments
|
||||||
|
if (!rb_obj_is_kind_of(_params, cCvSURFParams::rb_class())) {
|
||||||
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
||||||
|
rb_class2name(CLASS_OF(_params)), rb_class2name(cCvSURFParams::rb_class()));
|
||||||
|
}
|
||||||
|
CvSURFParams params = *CVSURFPARAMS(_params);
|
||||||
|
CvMat* mask;
|
||||||
|
if (NIL_P(_mask))
|
||||||
|
mask = NULL;
|
||||||
|
else {
|
||||||
|
if (!rb_obj_is_kind_of(_mask, cCvMat::rb_class())) {
|
||||||
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
||||||
|
rb_class2name(CLASS_OF(_mask)), rb_class2name(cCvMat::rb_class()));
|
||||||
|
}
|
||||||
|
mask = CVMAT(_mask);
|
||||||
|
}
|
||||||
|
CvSeq* keypoints;
|
||||||
|
if (NIL_P(_keypoints)) {
|
||||||
|
keypoints = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!rb_obj_is_kind_of(_keypoints, cCvSeq::rb_class())) {
|
||||||
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
|
||||||
|
rb_class2name(CLASS_OF(_keypoints)), rb_class2name(cCvSeq::rb_class()));
|
||||||
|
}
|
||||||
|
keypoints = CVSEQ(_keypoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
int use_provided = (keypoints == NULL) ? 0 : 1;
|
||||||
|
|
||||||
|
VALUE storage = cCvMemStorage::new_object();
|
||||||
|
CvSeq* descriptors = NULL;
|
||||||
|
|
||||||
|
// Compute SURF keypoints and descriptors
|
||||||
|
cvExtractSURF(CVARR(self), mask, &keypoints, &descriptors, CVMEMSTORAGE(storage),
|
||||||
|
params, use_provided);
|
||||||
|
_keypoints = cCvSeq::new_sequence(cCvSeq::rb_class(), keypoints, cCvSURFPoint::rb_class(), storage);
|
||||||
|
|
||||||
|
// Create descriptor array
|
||||||
|
const int DIM_SIZE = (params.extended) ? 128 : 64;
|
||||||
|
const int NUM_KEYPOINTS = keypoints->total;
|
||||||
|
VALUE _descriptors = rb_ary_new2(NUM_KEYPOINTS);
|
||||||
|
int m, n;
|
||||||
|
for (m = 0; m < NUM_KEYPOINTS; ++m) {
|
||||||
|
VALUE elem = rb_ary_new2(DIM_SIZE);
|
||||||
|
float *descriptor = (float*)cvGetSeqElem(descriptors, m);
|
||||||
|
for (n = 0; n < DIM_SIZE; ++n) {
|
||||||
|
rb_ary_store(elem, n, rb_float_new(descriptor[n]));
|
||||||
|
}
|
||||||
|
rb_ary_store(_descriptors, m, elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rb_assoc_new(_keypoints, _descriptors);
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
new_object(int rows, int cols, int type)
|
new_object(int rows, int cols, int type)
|
||||||
|
|
|
@ -265,6 +265,9 @@ VALUE rb_find_fundamental_mat_lmeds(int argc, VALUE *argv, VALUE klass);
|
||||||
VALUE rb_find_fundamental_mat(int argc, VALUE *argv, VALUE klass);
|
VALUE rb_find_fundamental_mat(int argc, VALUE *argv, VALUE klass);
|
||||||
VALUE rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_image, VALUE fundamental_matrix);
|
VALUE rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_image, VALUE fundamental_matrix);
|
||||||
|
|
||||||
|
/* Feature detection and description */
|
||||||
|
VALUE rb_extract_surf(int argc, VALUE *argv, VALUE self);
|
||||||
|
|
||||||
// HighGUI function
|
// HighGUI function
|
||||||
VALUE rb_save_image(VALUE self, VALUE filename);
|
VALUE rb_save_image(VALUE self, VALUE filename);
|
||||||
|
|
||||||
|
|
|
@ -1714,5 +1714,63 @@ class TestCvMat_imageprocessing < OpenCVTestCase
|
||||||
curr.optical_flow_bm(prev, 'foo', 'bar')
|
curr.optical_flow_bm(prev, 'foo', 'bar')
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_extract_surf
|
||||||
|
mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)
|
||||||
|
|
||||||
|
# simple
|
||||||
|
keypoints1, descriptors1 = mat0.extract_surf(CvSURFParams.new(500, true, 2, 3))
|
||||||
|
assert_equal(CvSeq, keypoints1.class)
|
||||||
|
assert_equal(254, keypoints1.size)
|
||||||
|
assert_equal(Array, descriptors1.class)
|
||||||
|
assert_equal(254, descriptors1.size)
|
||||||
|
assert_equal(Array, descriptors1[0].class)
|
||||||
|
assert_equal(128, descriptors1[0].size)
|
||||||
|
|
||||||
|
# use mask
|
||||||
|
mask = create_cvmat(mat0.rows, mat0.cols, :cv8u, 1) { |j, i|
|
||||||
|
if i < mat0.cols / 2
|
||||||
|
CvScalar.new(1)
|
||||||
|
else
|
||||||
|
CvScalar.new(0)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
keypoints2, descriptors2 = mat0.extract_surf(CvSURFParams.new(500, false), mask)
|
||||||
|
assert_equal(CvSeq, keypoints2.class)
|
||||||
|
assert_equal(170, keypoints2.size)
|
||||||
|
assert_equal(Array, descriptors2.class)
|
||||||
|
assert_equal(170, descriptors2.size)
|
||||||
|
assert_equal(Array, descriptors2[0].class)
|
||||||
|
assert_equal(64, descriptors2[0].size)
|
||||||
|
|
||||||
|
# use provided keypoints
|
||||||
|
keypoints3, descriptors3 = mat0.extract_surf(CvSURFParams.new(500, true), mask, keypoints1)
|
||||||
|
assert_equal(CvSeq, keypoints3.class)
|
||||||
|
assert_equal(254, keypoints3.size)
|
||||||
|
assert_equal(Array, descriptors3.class)
|
||||||
|
assert_equal(254, descriptors3.size)
|
||||||
|
|
||||||
|
# raise exceptions because of invalid arguments
|
||||||
|
assert_raise(TypeError) {
|
||||||
|
mat0.extract_surf(CvMat.new(1, 1, :cv8u))
|
||||||
|
}
|
||||||
|
assert_raise(TypeError) {
|
||||||
|
mat0.extract_surf(CvSURFParams.new(500), 'foobar')
|
||||||
|
}
|
||||||
|
assert_raise(TypeError) {
|
||||||
|
mat0.extract_surf(CvSURFParams.new(500), mask, mat0)
|
||||||
|
}
|
||||||
|
|
||||||
|
## Uncomment the following lines to show the result
|
||||||
|
# results = []
|
||||||
|
# [keypoints1, keypoints2, keypoints3].each { |kpts|
|
||||||
|
# tmp = mat0.GRAY2BGR
|
||||||
|
# kpts.each { |kp|
|
||||||
|
# tmp.circle!(kp.pt, 3, :color => CvColor::Red, :thickness => 1, :line_type => :aa)
|
||||||
|
# }
|
||||||
|
# results << tmp
|
||||||
|
# }
|
||||||
|
# snap mat0, *results
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue