1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00
ruby-opencv/ext/opencv/cascadeclassifier.cpp
Francois Deschenes ca813d4f71 Fixed warnings.
2018-07-24 22:37:05 -07:00

138 lines
4.4 KiB
C++

#include "opencv2/objdetect.hpp"
#include "opencv.hpp"
#include "mat.hpp"
#include "size.hpp"
#include "rect.hpp"
#include "error.hpp"
/*
* Document-class: Cv::CascadeClassifier
*/
namespace rubyopencv {
namespace CascadeClassifier {
void free_cascadeclassifier(void* ptr);
size_t memsize_cascadeclassifier(const void* ptr);
VALUE rb_klass = Qnil;
rb_data_type_t opencv_cascadeclassifier_type = {
"CascadeClassifier",
{ 0, free_cascadeclassifier, memsize_cascadeclassifier, },
0,
0,
0
};
void free_cascadeclassifier(void* ptr) {
delete (cv::CascadeClassifier*)ptr;
}
size_t memsize_cascadeclassifier(const void* ptr) {
return sizeof(cv::CascadeClassifier);
}
cv::CascadeClassifier* obj2cascadeclassifier(VALUE obj) {
cv::CascadeClassifier* ptr = NULL;
TypedData_Get_Struct(obj, cv::CascadeClassifier, &opencv_cascadeclassifier_type, ptr);
return ptr;
}
VALUE rb_allocate(VALUE klass) {
cv::CascadeClassifier* ptr = new cv::CascadeClassifier();
return TypedData_Wrap_Struct(klass, &opencv_cascadeclassifier_type, ptr);
}
VALUE rb_initialize(int argc, VALUE *argv, VALUE self) {
VALUE filename;
rb_scan_args(argc, argv, "01", &filename);
cv::CascadeClassifier* selfptr = obj2cascadeclassifier(self);
if (!NIL_P(filename)) {
selfptr->load(StringValueCStr(filename));
}
return self;
}
VALUE rb_load(VALUE self, VALUE filename) {
cv::CascadeClassifier* selfptr = obj2cascadeclassifier(self);
bool ret = selfptr->load(StringValueCStr(filename));
return ret ? Qtrue : Qfalse;
}
/*
* Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.
*
* @overload detect_multi_scale(image, options = nil)
* @param image [Mat] Matrix of the type CV_8U containing an image where objects are detected.
* @param options [Hash] Options
* @option options [Number] :scale_factor
* Parameter specifying how much the image size is reduced at each image scale.
* @option options [Integer] :min_neighbors
* Parameter specifying how many neighbors each candidate rectangle should have to retain it.
* @option options [Size] :min_size
* Minimum possible object size. Objects smaller than that are ignored.
* @option options [Size] :max_size
* Maximum possible object size. Objects larger than that are ignored.
* @return [Array<Rect>] Detected objects as a list of rectangles.
* @opencv_func cv::CascadeClassifier::detectMultiScale
*/
VALUE rb_detect_multi_scale(int argc, VALUE *argv, VALUE self) {
VALUE image, options;
rb_scan_args(argc, argv, "11", &image, &options);
cv::CascadeClassifier* selfptr = obj2cascadeclassifier(self);
std::vector<cv::Rect> objects;
try {
cv::Mat* m = Mat::obj2mat(image);
if (NIL_P(options)) {
selfptr->detectMultiScale(*m, objects);
}
else {
Check_Type(options, T_HASH);
double scale_factor = NUM2DBL_DEFAULT(HASH_LOOKUP(options, "scale_factor"), 1.1);
int min_neighbors = NUM2INT_DEFAULT(HASH_LOOKUP(options, "min_neighbors"), 3);
cv::Size min_size;
cv::Size max_size;
VALUE tmp = Qnil;
tmp = rb_hash_lookup(options, ID2SYM(rb_intern("min_size")));
if (!NIL_P(tmp)) {
min_size = *(Size::obj2size(tmp));
}
tmp = rb_hash_lookup(options, ID2SYM(rb_intern("max_size")));
if (!NIL_P(tmp)) {
max_size = *(Size::obj2size(tmp));
}
selfptr->detectMultiScale(*m, objects, scale_factor, min_neighbors, 0, min_size, max_size);
}
}
catch (cv::Exception& e) {
Error::raise(e);
}
const long size = objects.size();
VALUE detected_objects = rb_ary_new_capa(size);
for (long i = 0; i < size; i++) {
VALUE v = Rect::rect2obj(objects[i]);
rb_ary_store(detected_objects, i, v);
}
return detected_objects;
}
void init() {
VALUE opencv = rb_define_module("Cv");
rb_klass = rb_define_class_under(opencv, "CascadeClassifier", rb_cData);
rb_define_alloc_func(rb_klass, rb_allocate);
rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
rb_define_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load), 1);
rb_define_method(rb_klass, "detect_multi_scale", RUBY_METHOD_FUNC(rb_detect_multi_scale), -1);
}
}
}