Merge branch 'templateMatches' of https://github.com/oskardahlberg/node-opencv into oskardahlberg-templateMatches

Conflicts:
	src/Matrix.cc
This commit is contained in:
Peter Braden 2015-02-11 18:46:13 +01:00
commit aa8ee12587
2 changed files with 83 additions and 0 deletions

View File

@ -82,6 +82,7 @@ Matrix::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(ctor, "equalizeHist", EqualizeHist);
NODE_SET_PROTOTYPE_METHOD(ctor, "floodFill", FloodFill);
NODE_SET_PROTOTYPE_METHOD(ctor, "matchTemplate", MatchTemplate);
NODE_SET_PROTOTYPE_METHOD(ctor, "templateMatches", TemplateMatches);
NODE_SET_PROTOTYPE_METHOD(ctor, "minMaxLoc", MinMaxLoc);
NODE_SET_PROTOTYPE_METHOD(ctor, "pushBack", PushBack);
NODE_SET_PROTOTYPE_METHOD(ctor, "putText", PutText);
@ -1726,6 +1727,87 @@ NAN_METHOD(Matrix::FloodFill){
NanReturnValue(NanNew<Number>( ret ));
}
// @author olfox
// Returns an array of the most probable positions
// Usage: output = input.templateMatches(min_probability, max_probability, limit, ascending, min_x_distance, min_y_distance);
Handle<Value>
Matrix::TemplateMatches(const v8::Arguments& args) {
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
bool filter_min_probability = (args.Length() >= 1) ? args[0]->IsNumber() : false;
bool filter_max_probability = (args.Length() >= 2) ? args[1]->IsNumber() : false;
double min_probability = filter_min_probability ? args[0]->NumberValue() : 0;
double max_probability = filter_max_probability ? args[1]->NumberValue() : 0;
int limit = (args.Length() >= 3) ? args[2]->IntegerValue() : 0;
bool ascending = (args.Length() >= 4) ? args[3]->BooleanValue() : false;
int min_x_distance = (args.Length() >= 5) ? args[4]->IntegerValue() : 0;
int min_y_distance = (args.Length() >= 6) ? args[5]->IntegerValue() : 0;
cv::Mat_<int> indices;
if (ascending)
cv::sortIdx(self->mat.reshape(0,1), indices, CV_SORT_ASCENDING + CV_SORT_EVERY_ROW);
else
cv::sortIdx(self->mat.reshape(0,1), indices, CV_SORT_DESCENDING + CV_SORT_EVERY_ROW);
cv::Mat hit_mask = cv::Mat::zeros(self->mat.size(), CV_64F);
v8::Local<v8::Array> probabilites_array = v8::Array::New();
cv::Mat_<float>::const_iterator begin = self->mat.begin<float>();
cv::Mat_<int>::const_iterator it = indices.begin();
cv::Mat_<int>::const_iterator end = indices.end();
int index = 0;
for (; (limit == 0 || index < limit) && it != end; ++it) {
cv::Point pt = (begin + *it).pos();
float probability = self->mat.at<float>(pt.y, pt.x);
if (filter_min_probability && probability < min_probability) {
if (ascending) continue;
else break;
}
if (filter_max_probability && probability > max_probability) {
if (ascending) break;
else continue;
}
if (min_x_distance != 0 || min_y_distance != 0) {
// Check hit mask color for for every corner
cv::Size maxSize = hit_mask.size();
int max_x = maxSize.width - 1;
int max_y = maxSize.height - 1;
cv::Point top_left = cv::Point(max(0, pt.x - min_x_distance), max(0, pt.y - min_y_distance));
cv::Point top_right = cv::Point(min(max_x, pt.x + min_x_distance), max(0, pt.y - min_y_distance));
cv::Point bottom_left = cv::Point(max(0, pt.x - min_x_distance), min(max_y, pt.y + min_y_distance));
cv::Point bottom_right = cv::Point(min(max_x, pt.x + min_x_distance), min(max_y, pt.y + min_y_distance));
if (hit_mask.at<double>(top_left.y, top_left.x) > 0) continue;
if (hit_mask.at<double>(top_right.y, top_right.x) > 0) continue;
if (hit_mask.at<double>(bottom_left.y, bottom_left.x) > 0) continue;
if (hit_mask.at<double>(bottom_right.y, bottom_right.x) > 0) continue;
cv::Scalar color(255.0);
cv::rectangle(hit_mask, top_left, bottom_right, color, CV_FILLED);
}
Local<Value> x_value = v8::Number::New(pt.x);
Local<Value> y_value = v8::Number::New(pt.y);
Local<Value> probability_value = v8::Number::New(probability);
Local<Object> probability_object = Object::New();
probability_object->Set(String::NewSymbol("x"), x_value);
probability_object->Set(String::NewSymbol("y"), y_value);
probability_object->Set(String::NewSymbol("probability"), probability_value);
probabilites_array->Set(index, probability_object);
index++;
}
return scope.Close(probabilites_array);
}
// @author ytham
// Match Template filter
// Usage: output = input.matchTemplate("templateFileString", method);

View File

@ -96,6 +96,7 @@ class Matrix: public node::ObjectWrap {
JSFUNC(FloodFill)
JSFUNC(MatchTemplate)
JSFUNC(TemplateMatches)
JSFUNC(MinMaxLoc)
JSFUNC(PushBack)