mirror of
https://github.com/ruby-opencv/ruby-opencv
synced 2023-03-27 23:22:12 -04:00
modified arguments of CvHaarClassifierCascade#detect_objects to set options more easily
This commit is contained in:
parent
ca24f705ac
commit
5266eb051a
6 changed files with 77 additions and 58 deletions
|
@ -43,7 +43,6 @@ void define_ruby_class()
|
||||||
rb_define_alloc_func(rb_klass, rb_allocate);
|
rb_define_alloc_func(rb_klass, rb_allocate);
|
||||||
rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load), 1);
|
rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load), 1);
|
||||||
rb_define_method(rb_klass, "detect_objects", RUBY_METHOD_FUNC(rb_detect_objects), -1);
|
rb_define_method(rb_klass, "detect_objects", RUBY_METHOD_FUNC(rb_detect_objects), -1);
|
||||||
rb_define_method(rb_klass, "detect_objects_with_pruning", RUBY_METHOD_FUNC(rb_detect_objects_with_pruning), -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -86,74 +85,72 @@ rb_load(VALUE klass, VALUE path)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* detect_objects(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]) -> cvseq(include CvAvgComp object)
|
* detect_objects(image[, options]) -> cvseq(include CvAvgComp object)
|
||||||
* detect_objects(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]){|cmp| ... } -> cvseq(include CvAvgComp object)
|
* detect_objects(image[, options]){|cmp| ... } -> cvseq(include CvAvgComp object)
|
||||||
*
|
*
|
||||||
* Detects objects in the image. This method finds rectangular regions in the
|
* Detects objects in the image. This method finds rectangular regions in the
|
||||||
* given image that are likely to contain objects the cascade has been trained
|
* given image that are likely to contain objects the cascade has been trained
|
||||||
* for and return those regions as a sequence of rectangles.
|
* for and return those regions as a sequence of rectangles.
|
||||||
*
|
*
|
||||||
* * scale_factor (should be > 1.0)
|
* * <i>option</i> should be Hash include these keys.
|
||||||
* The factor by which the search window is scaled between the subsequent scans, for example, 1.1 mean increasing window by 10%.
|
* :scale_factor (should be > 1.0)
|
||||||
* * min_neighbors
|
* The factor by which the search window is scaled between the subsequent scans,
|
||||||
|
* 1.1 mean increasing window by 10%.
|
||||||
|
* :storage
|
||||||
|
* Memory storage to store the resultant sequence of the object candidate rectangles
|
||||||
|
* :flags
|
||||||
|
* Mode of operation. Currently the only flag that may be specified is CV_HAAR_DO_CANNY_PRUNING .
|
||||||
|
* If it is set, the function uses Canny edge detector to reject some image regions that contain
|
||||||
|
* too few or too much edges and thus can not contain the searched object. The particular threshold
|
||||||
|
* values are tuned for face detection and in this case the pruning speeds up the processing
|
||||||
|
* :min_neighbors
|
||||||
* Minimum number (minus 1) of neighbor rectangles that makes up an object.
|
* Minimum number (minus 1) of neighbor rectangles that makes up an object.
|
||||||
* All the groups of a smaller number of rectangles than min_neighbors - 1 are rejected.
|
* All the groups of a smaller number of rectangles than min_neighbors - 1 are rejected.
|
||||||
* If min_neighbors is 0, the function does not any grouping at all and returns all the detected
|
* If min_neighbors is 0, the function does not any grouping at all and returns all the detected
|
||||||
* candidate rectangles, whitch many be useful if the user wants to apply a customized grouping procedure.
|
* candidate rectangles, whitch many be useful if the user wants to apply a customized grouping procedure.
|
||||||
* * min_size
|
* :min_size
|
||||||
* Minimum window size. By default, it is set to size of samples the classifier has been trained on.
|
* Minimum window size. By default, it is set to size of samples the classifier has been
|
||||||
|
* trained on (~20x20 for face detection).
|
||||||
|
* :max_size
|
||||||
|
* aximum window size to use. By default, it is set to the size of the image.
|
||||||
*/
|
*/
|
||||||
VALUE
|
VALUE
|
||||||
rb_detect_objects(int argc, VALUE *argv, VALUE self)
|
rb_detect_objects(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
VALUE image, storage, scale_factor, min_neighbors, min_size, result;
|
VALUE image, options;
|
||||||
rb_scan_args(argc, argv, "14", &image, &storage, &scale_factor, &min_neighbors, &min_size);
|
rb_scan_args(argc, argv, "11", &image, &options);
|
||||||
|
|
||||||
if (!rb_obj_is_kind_of(image, cCvMat::rb_class()))
|
if (!rb_obj_is_kind_of(image, cCvMat::rb_class()))
|
||||||
rb_raise(rb_eTypeError, "argument 1(target-image) should be %s.", rb_class2name(cCvMat::rb_class()));
|
rb_raise(rb_eTypeError, "argument 1(target-image) should be %s.", rb_class2name(cCvMat::rb_class()));
|
||||||
double scale = IF_DBL(scale_factor, 1.1);
|
|
||||||
if (!(scale > 1.0))
|
double scale_factor;
|
||||||
rb_raise(rb_eArgError, "argument 2 (scale factor) must > 1.0.");
|
int flags, min_neighbors;
|
||||||
storage = CHECK_CVMEMSTORAGE(storage);
|
CvSize min_size, max_size;
|
||||||
CvSeq *seq = cvHaarDetectObjects(CVMAT(image), CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage),
|
VALUE storage_val;
|
||||||
scale, IF_INT(min_neighbors, 3), 0, NIL_P(min_size) ? cvSize(0,0) : VALUE_TO_CVSIZE(min_size));
|
if (NIL_P(options)) {
|
||||||
result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage);
|
scale_factor = 1.1;
|
||||||
if (rb_block_given_p()) {
|
flags = 0;
|
||||||
for(int i = 0; i < seq->total; i++)
|
min_neighbors = 3;
|
||||||
rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage));
|
min_size = max_size = cvSize(0, 0);
|
||||||
|
storage_val = cCvMemStorage::new_object();
|
||||||
}
|
}
|
||||||
return result;
|
else {
|
||||||
|
scale_factor = IF_DBL(LOOKUP_CVMETHOD(options, "scale_factor"), 1.1);
|
||||||
|
flags = IF_INT(LOOKUP_CVMETHOD(options, "flags"), 0);
|
||||||
|
min_neighbors = IF_INT(LOOKUP_CVMETHOD(options, "min_neighbors"), 3);
|
||||||
|
VALUE min_size_val = LOOKUP_CVMETHOD(options, "min_size");
|
||||||
|
min_size = NIL_P(min_size_val) ? cvSize(0, 0) : VALUE_TO_CVSIZE(min_size_val);
|
||||||
|
VALUE max_size_val = LOOKUP_CVMETHOD(options, "max_size");
|
||||||
|
max_size = NIL_P(max_size_val) ? cvSize(0, 0) : VALUE_TO_CVSIZE(max_size_val);
|
||||||
|
storage_val = CHECK_CVMEMSTORAGE(LOOKUP_CVMETHOD(options, "storage"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
CvSeq *seq = cvHaarDetectObjects(CVMAT(image), CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage_val),
|
||||||
* call-seq:
|
scale_factor, min_neighbors, flags, min_size, max_size);
|
||||||
* detect_objects_with_pruning(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]) -> cvseq(include CvAvgComp object)
|
VALUE result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage_val);
|
||||||
* detect_objects_with_pruning(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]){|cmp| ... } -> cvseq(include CvAvgComp object)
|
|
||||||
*
|
|
||||||
* Almost same to #detect_objects (Return detected objects).
|
|
||||||
*
|
|
||||||
* Before scanning to image, Canny edge detector to reject some image regions
|
|
||||||
* that contain too few or too much edges, and thus can not contain the searched object.
|
|
||||||
*
|
|
||||||
* note: The particular threshold values are tuned for face detection.
|
|
||||||
* And in this case the pruning speeds up the processing.
|
|
||||||
*/
|
|
||||||
VALUE
|
|
||||||
rb_detect_objects_with_pruning(int argc, VALUE *argv, VALUE self)
|
|
||||||
{
|
|
||||||
VALUE image, storage, scale_factor, min_neighbors, min_size, result;
|
|
||||||
rb_scan_args(argc, argv, "14", &image, &storage, &scale_factor, &min_neighbors, &min_size);
|
|
||||||
if (!rb_obj_is_kind_of(image, cCvMat::rb_class()))
|
|
||||||
rb_raise(rb_eTypeError, "argument 1(target-image) should be %s.", rb_class2name(cCvMat::rb_class()));
|
|
||||||
double scale = IF_DBL(scale_factor, 1.1);
|
|
||||||
if (!(scale > 1.0))
|
|
||||||
rb_raise(rb_eArgError, "argument 2 (scale factor) must > 1.0.");
|
|
||||||
storage = CHECK_CVMEMSTORAGE(storage);
|
|
||||||
CvSeq *seq = cvHaarDetectObjects(CVMAT(image), CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage),
|
|
||||||
scale, IF_INT(min_neighbors, 3), CV_HAAR_DO_CANNY_PRUNING, NIL_P(min_size) ? cvSize(0,0) : VALUE_TO_CVSIZE(min_size));
|
|
||||||
result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage);
|
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
for(int i = 0; i < seq->total; i++)
|
for(int i = 0; i < seq->total; ++i)
|
||||||
rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage));
|
rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage_val));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ VALUE rb_allocate(VALUE klass);
|
||||||
|
|
||||||
VALUE rb_load(VALUE klass, VALUE path);
|
VALUE rb_load(VALUE klass, VALUE path);
|
||||||
VALUE rb_detect_objects(int argc, VALUE *argv, VALUE self);
|
VALUE rb_detect_objects(int argc, VALUE *argv, VALUE self);
|
||||||
VALUE rb_detect_objects_with_pruning(int argc, VALUE *argv, VALUE self);
|
|
||||||
|
|
||||||
__NAMESPACE_END_CVHAARCLASSIFERCASCADE
|
__NAMESPACE_END_CVHAARCLASSIFERCASCADE
|
||||||
inline CvHaarClassifierCascade *CVHAARCLASSIFIERCASCADE(VALUE object) {
|
inline CvHaarClassifierCascade *CVHAARCLASSIFIERCASCADE(VALUE object) {
|
||||||
|
|
|
@ -413,6 +413,9 @@ define_ruby_module()
|
||||||
/* Flags of window */
|
/* Flags of window */
|
||||||
rb_define_const(rb_module, "CV_WINDOW_AUTOSIZE", INT2FIX(CV_WINDOW_AUTOSIZE));
|
rb_define_const(rb_module, "CV_WINDOW_AUTOSIZE", INT2FIX(CV_WINDOW_AUTOSIZE));
|
||||||
|
|
||||||
|
/* Object detection mode */
|
||||||
|
rb_define_const(rb_module, "CV_HAAR_DO_CANNY_PRUNING", INT2FIX(CV_HAAR_DO_CANNY_PRUNING));
|
||||||
|
|
||||||
VALUE inversion_method = rb_hash_new();
|
VALUE inversion_method = rb_hash_new();
|
||||||
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */
|
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */
|
||||||
rb_define_const(rb_module, "INVERSION_METHOD", inversion_method);
|
rb_define_const(rb_module, "INVERSION_METHOD", inversion_method);
|
||||||
|
|
|
@ -145,6 +145,7 @@ extern "C"{
|
||||||
#define IF_DEPTH(val, ifnone) NIL_P(val) ? ifnone : FIX2INT(val)
|
#define IF_DEPTH(val, ifnone) NIL_P(val) ? ifnone : FIX2INT(val)
|
||||||
|
|
||||||
#define RESIST_CVMETHOD(hash, str, value) rb_hash_aset(hash, ID2SYM(rb_intern(str)), INT2FIX(value))
|
#define RESIST_CVMETHOD(hash, str, value) rb_hash_aset(hash, ID2SYM(rb_intern(str)), INT2FIX(value))
|
||||||
|
#define LOOKUP_CVMETHOD(hash, key_as_cstr) (rb_hash_lookup(hash, ID2SYM(rb_intern(key_as_cstr))))
|
||||||
|
|
||||||
#define maxint(a,b) ({int _a = (a), _b = (b); _a > _b ? _a : _b; })
|
#define maxint(a,b) ({int _a = (a), _b = (b); _a > _b ? _a : _b; })
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,22 @@ class TestCvHaarClassifierCascade < OpenCVTestCase
|
||||||
assert_equal(CvSeq, detected.class)
|
assert_equal(CvSeq, detected.class)
|
||||||
assert_equal(1, detected.size)
|
assert_equal(1, detected.size)
|
||||||
assert_equal(CvAvgComp, detected[0].class)
|
assert_equal(CvAvgComp, detected[0].class)
|
||||||
|
|
||||||
|
detected = @cascade.detect_objects(img, :scale_factor => 2.0, :flags => CV_HAAR_DO_CANNY_PRUNING,
|
||||||
|
:min_neighbors => 5, :min_size => CvSize.new(10, 10),
|
||||||
|
:max_size => CvSize.new(100, 100))
|
||||||
|
assert_equal(CvSeq, detected.class)
|
||||||
|
assert_equal(1, detected.size)
|
||||||
|
assert_equal(CvAvgComp, detected[0].class)
|
||||||
|
assert_equal(109, detected[0].x)
|
||||||
|
assert_equal(102, detected[0].y)
|
||||||
|
assert_equal(80, detected[0].width)
|
||||||
|
assert_equal(80, detected[0].height)
|
||||||
|
assert_equal(7, detected[0].neighbors)
|
||||||
|
|
||||||
|
assert_raise(TypeError) {
|
||||||
|
@cascade.detect_objects('foo')
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,9 @@ class TestOpenCV < OpenCVTestCase
|
||||||
|
|
||||||
# Flags of window
|
# Flags of window
|
||||||
assert_equal(1, CV_WINDOW_AUTOSIZE)
|
assert_equal(1, CV_WINDOW_AUTOSIZE)
|
||||||
|
|
||||||
|
# Object detection mode
|
||||||
|
assert_equal(1, CV_HAAR_DO_CANNY_PRUNING)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_symbols
|
def test_symbols
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue