Skip to content
This repository was archived by the owner on Oct 18, 2023. It is now read-only.

Commit f2c9610

Browse files
committedJul 29, 2017
imgproc types + warpPerspective + testcases
1 parent 2eeeb02 commit f2c9610

25 files changed

+364
-75
lines changed
 

‎binding.gyp

+2
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@
5757
"cc/index.cc",
5858
"cc/core/Mat.cc",
5959
"cc/core/Point.cc",
60+
"cc/core/Size.cc",
6061
"cc/modules/io.cc",
6162
"cc/modules/photo.cc",
6263
"cc/modules/calib3d/calib3d.cc",
64+
"cc/modules/imgproc/imgproc.cc",
6365
"cc/modules/features2d/features2d.cc",
6466
"cc/modules/features2d/KeyPoint.cc",
6567
"cc/modules/features2d/KeyPointMatch.cc",

‎cc/core/Mat.cc

+39-1
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,16 @@ NAN_MODULE_INIT(Mat::Init) {
1313
Nan::SetAccessor(ctor->InstanceTemplate(), Nan::New("type").ToLocalChecked(), Mat::GetType);
1414

1515
Nan::SetPrototypeMethod(ctor, "getData", GetData);
16+
Nan::SetPrototypeMethod(ctor, "row", Row);
17+
18+
/* #IFDEF IMGPROC */
1619
Nan::SetPrototypeMethod(ctor, "rescale", Rescale);
1720
Nan::SetPrototypeMethod(ctor, "resize", Resize);
1821
Nan::SetPrototypeMethod(ctor, "resizeToMax", ResizeToMax);
19-
Nan::SetPrototypeMethod(ctor, "row", Row);
22+
Nan::SetPrototypeMethod(ctor, "warpPerspective", WarpPerspective);
23+
/* #ENDIF IMGPROC */
24+
25+
2026

2127
v8::Local<v8::Object> matTypesModule = Nan::New<v8::Object>();
2228
initMatTypes(matTypesModule);
@@ -54,6 +60,8 @@ NAN_METHOD(Mat::GetData) {
5460
info.GetReturnValue().Set(FF::matDataToJsArray(Nan::ObjectWrap::Unwrap<Mat>(info.This())->mat));
5561
}
5662

63+
/* #IFDEC IMGPROC */
64+
5765
NAN_METHOD(Mat::Rescale) {
5866
if (!info[0]->IsNumber()) {
5967
return Nan::ThrowError("usage: rescale(double factor)");
@@ -104,6 +112,36 @@ NAN_METHOD(Mat::ResizeToMax) {
104112
info.GetReturnValue().Set(handle);
105113
}
106114

115+
NAN_METHOD(Mat::WarpPerspective) {
116+
if (!info[0]->IsObject()) {
117+
// TODO usage messages
118+
return Nan::ThrowError(FF_V8STRING("warpPerspective - args object required"));
119+
}
120+
Mat* self = Nan::ObjectWrap::Unwrap<Mat>(info.This());
121+
v8::Local<v8::Object> args = info[0]->ToObject();
122+
v8::Local<v8::Object> jsTransformMat;
123+
FF_GET_JSPROP_REQUIRED(args, jsTransformMat, transformationMatrix, ToObject);
124+
cv::Mat transformationMatrix = Nan::ObjectWrap::Unwrap<Mat>(jsTransformMat)->mat;
125+
cv::Size size = cv::Size(self->mat.cols, self->mat.rows);
126+
if (args->HasOwnProperty(FF_V8STRING("size"))) {
127+
Nan::ObjectWrap::Unwrap<Size>(FF_GET_JSPROP(args, size)->ToObject())->size;
128+
}
129+
int flags = cv::INTER_LINEAR;
130+
int borderMode = cv::BORDER_CONSTANT;
131+
// TODO borderValue
132+
const cv::Scalar& borderValue = cv::Scalar();
133+
134+
FF_DESTRUCTURE_TYPECHECKED_JSPROP_IFDEF(args, flags, IsInt32, Int32Value);
135+
FF_DESTRUCTURE_TYPECHECKED_JSPROP_IFDEF(args, borderMode, IsInt32, Int32Value);
136+
137+
v8::Local<v8::Object> jsMat = Nan::NewInstance(Nan::New(constructor)->GetFunction()).ToLocalChecked();
138+
cv::warpPerspective(self->mat, Nan::ObjectWrap::Unwrap<Mat>(jsMat)->mat, transformationMatrix, size, flags, borderMode, borderValue);
139+
140+
info.GetReturnValue().Set(jsMat);
141+
}
142+
143+
/* #ENDIF IMGPROC */
144+
107145
NAN_METHOD(Mat::Row) {
108146
if (!info[0]->IsNumber()) {
109147
return Nan::ThrowError("usage: row(int r)");

‎cc/core/Mat.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <nan.h>
22
#include "../macros.h"
33
#include "matTypes.h"
4+
#include "Size.h"
45
#include <opencv2/imgproc.hpp>
56
#include <iostream>
67

@@ -12,16 +13,21 @@ class Mat : public Nan::ObjectWrap {
1213
cv::Mat mat;
1314

1415
static NAN_MODULE_INIT(Init);
16+
static NAN_METHOD(New);
1517

1618
static FF_GETTER(Mat, GetRows, mat.rows);
1719
static FF_GETTER(Mat, GetCols, mat.cols);
1820
static FF_GETTER(Mat, GetType, mat.type());
1921

20-
static NAN_METHOD(New);
2122
static NAN_METHOD(GetData);
23+
24+
/* #IFDEF IMGPROC */
2225
static NAN_METHOD(Rescale);
2326
static NAN_METHOD(Resize);
2427
static NAN_METHOD(ResizeToMax);
28+
static NAN_METHOD(WarpPerspective);
29+
/* #ENDIF IMGPROC */
30+
2531
static NAN_METHOD(Row);
2632

2733
static Nan::Persistent<v8::FunctionTemplate> Mat::constructor;

‎cc/core/Point.h

+11-16
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,29 @@
1010
class Point : public Nan::ObjectWrap {
1111
public:
1212
static NAN_MODULE_INIT(Init);
13-
1413
static NAN_METHOD(New);
1514
static NAN_METHOD(NewPoint2);
1615
static NAN_METHOD(NewPoint3);
1716

18-
static std::vector<cv::Point2d> unpackJSPoint2Array(v8::Local<v8::Array> jsPts) {
19-
std::vector<cv::Point2d> pts;
17+
static void unpackJSPoint2Array(std::vector<cv::Point2d> &pts, v8::Local<v8::Array> jsPts) {
2018
for (uint i = 0; i < jsPts->Length(); i++) {
2119
v8::Local<v8::Object> obj = Nan::To<v8::Object>(jsPts->Get(i)).ToLocalChecked();
22-
pts.push_back(cv::Point2d(
23-
FF::getCheckedJsProp(obj, "x")->NumberValue(),
24-
FF::getCheckedJsProp(obj, "y")->NumberValue()
25-
));
20+
double x, y;
21+
FF_DESTRUCTURE_JSPROP_REQUIRED(obj, x, NumberValue)
22+
FF_DESTRUCTURE_JSPROP_REQUIRED(obj, y, NumberValue)
23+
pts.push_back(cv::Point2d(x, y));
2624
}
27-
return pts;
2825
};
2926

30-
static std::vector<cv::Point3d> unpackJSPoint3Array(v8::Local<v8::Array> jsPts) {
31-
std::vector<cv::Point3d> pts;
27+
static void unpackJSPoint3Array(std::vector<cv::Point3d> &pts, v8::Local<v8::Array> jsPts) {
3228
for (uint i = 0; i < jsPts->Length(); i++) {
3329
v8::Local<v8::Object> obj = Nan::To<v8::Object>(jsPts->Get(i)).ToLocalChecked();
34-
pts.push_back(cv::Point3d(
35-
FF::getCheckedJsProp(obj, "x")->NumberValue(),
36-
FF::getCheckedJsProp(obj, "y")->NumberValue(),
37-
FF::getCheckedJsProp(obj, "z")->NumberValue()
38-
));
30+
double x, y, z;
31+
FF_DESTRUCTURE_JSPROP_REQUIRED(obj, x, NumberValue)
32+
FF_DESTRUCTURE_JSPROP_REQUIRED(obj, y, NumberValue)
33+
FF_DESTRUCTURE_JSPROP_REQUIRED(obj, z, NumberValue)
34+
pts.push_back(cv::Point3d(x, y, z));
3935
}
40-
return pts;
4136
};
4237

4338
static Nan::Persistent<v8::FunctionTemplate> Point::constructor;

‎cc/core/Size.cc

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "Size.h"
2+
3+
Nan::Persistent<v8::FunctionTemplate> Size::constructor;
4+
5+
NAN_MODULE_INIT(Size::Init) {
6+
v8::Local<v8::FunctionTemplate> ctor = Nan::New<v8::FunctionTemplate>(Size::New);
7+
Size::constructor.Reset(ctor);
8+
ctor->InstanceTemplate()->SetInternalFieldCount(1);
9+
ctor->SetClassName(Nan::New("Size").ToLocalChecked());
10+
Nan::SetAccessor(ctor->InstanceTemplate(), Nan::New("width").ToLocalChecked(), Size::GetWidth);
11+
Nan::SetAccessor(ctor->InstanceTemplate(), Nan::New("height").ToLocalChecked(), Size::GetHeight);
12+
13+
target->Set(Nan::New("Size").ToLocalChecked(), ctor->GetFunction());
14+
};
15+
16+
NAN_METHOD(Size::New) {
17+
if (info.Length() < 2) {
18+
return Nan::ThrowError("Size::New - expected arguments width, height");
19+
}
20+
double width = info[0]->NumberValue();
21+
double height = info[1]->NumberValue();
22+
23+
Size* self = new Size();
24+
self->size = cv::Size2d(width, height);
25+
self->Wrap(info.Holder());
26+
info.GetReturnValue().Set(info.Holder());
27+
}

‎cc/core/Size.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <nan.h>
2+
#include <opencv2/core.hpp>
3+
#include "macros.h"
4+
5+
#ifndef __FF_SIZE_H__
6+
#define __FF_SIZE_H__
7+
8+
class Size : public Nan::ObjectWrap {
9+
public:
10+
cv::Size2d size;
11+
12+
static NAN_MODULE_INIT(Init);
13+
static NAN_METHOD(New);
14+
15+
static FF_GETTER(Size, GetWidth, size.width);
16+
static FF_GETTER(Size, GetHeight, size.height);
17+
18+
static Nan::Persistent<v8::FunctionTemplate> Size::constructor;
19+
};
20+
21+
#endif

‎cc/index.cc

+5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
#include <node.h>
22
#include "Mat.h"
33
#include "Point.h"
4+
#include "Size.h"
45

56
#include "modules/io.h"
67
#include "modules/photo.h"
78
#include "modules/calib3d/calib3d.h"
9+
#include "modules/imgproc/imgproc.h"
810
#include "modules/features2d/features2d.h"
911
#include "modules/xfeatures2d/xfeatures2d.h"
1012
#include "modules/sfm/sfm.h"
1113

14+
// TODO core index
1215
void init(v8::Local<v8::Object> target) {
1316
Mat::Init(target);
1417
Point::Init(target);
18+
Size::Init(target);
1519
Io::Init(target);
1620
Photo::Init(target);
1721
Calib3d::Init(target);
22+
Imgproc::Init(target);
1823
Features2d::Init(target);
1924
XFeatures2d::Init(target);
2025
Sfm::Init(target);

‎cc/macros.h

+30-16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#define FF_GETTER(clazz, name, value) \
1515
NAN_GETTER(name) { info.GetReturnValue().Set(Nan::ObjectWrap::Unwrap<clazz>(info.This())->value); }
1616

17+
#define FF_SET_JS_PROP(obj, prop, val) \
18+
Nan::Set(obj, FF_V8STRING(#prop), val)
19+
1720
/* unchecked js prop getters */
1821

1922
#define FF_GET_JSPROP(obj, prop) \
@@ -40,13 +43,33 @@
4043
#define FF_GET_JSPROP_STRING(obj, prop) \
4144
FF_JS_VAL_TO_STRING(FF_GET_JSPROP(obj, prop)->ToString())
4245

43-
#define FF_TRY(work) \
44-
try { \
45-
work \
46-
} catch (std::exception &e) { \
47-
return Nan::ThrowError(e.what()); \
48-
} catch (...) { \
49-
return Nan::ThrowError("SEGFAULT"); \
46+
/* checked js prop getters */
47+
48+
#define FF_GET_JSPROP_REQUIRED(obj, var, prop, castType) \
49+
if (!obj->HasOwnProperty(FF_V8STRING(#prop))) { \
50+
return Nan::ThrowError(FF_V8STRING("Object has no property: " + std::string(#prop))); \
51+
} \
52+
var = FF_GET_JSPROP(obj, prop)->castType();
53+
54+
#define FF_DESTRUCTURE_JSPROP_REQUIRED(obj, prop, castType) \
55+
FF_GET_JSPROP_REQUIRED(obj, prop, prop, castType)
56+
57+
#define FF_TRY(work) \
58+
try { \
59+
work \
60+
} catch (std::exception &e) { \
61+
return info.GetReturnValue().Set(Nan::Error(e.what())); \
62+
} catch (...) { \
63+
return info.GetReturnValue().Set(Nan::Error("SEGFAULT")); \
64+
}
65+
66+
#define FF_TRY_CATCH(work) \
67+
try { \
68+
work \
69+
} catch (std::exception &e) { \
70+
Nan::ThrowError(e.what()); \
71+
} catch (...) { \
72+
Nan::ThrowError("SEGFAULT"); \
5073
}
5174

5275
#define FF_MAT_TO_JS_ARR(data, rows, cols) \
@@ -68,15 +91,6 @@
6891
FF_GET_TYPECHECKED_JSPROP_IFDEF(obj, prop, prop, assertType, castType)
6992

7093
namespace FF {
71-
/* checked js prop getters */
72-
73-
static inline v8::Local<v8::Value> getCheckedJsProp(v8::Local<v8::Object> obj, char* prop) {
74-
if (!obj->HasOwnProperty(FF_V8STRING(prop))) {
75-
Nan::ThrowError(FF_V8STRING("Object has no property: " + std::string(prop)));
76-
}
77-
return Nan::Get(obj, FF_V8STRING(prop)).ToLocalChecked();
78-
}
79-
8094
static inline v8::Local<v8::Array> matrixdToJsArray(Eigen::MatrixXd vec) {
8195
v8::Local<v8::Array> jsVec = Nan::New<v8::Array>(vec.rows());
8296
for (int r = 0; r < vec.rows(); r++) {

‎cc/modules/calib3d/calib3d.cc

+19-8
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,37 @@
11
#include "calib3d.h"
22

3-
#define FF_SET_JS_PROP(obj, prop, val) \
4-
Nan::Set(obj, FF_V8STRING(#prop), val)
5-
63
NAN_MODULE_INIT(Calib3d::Init) {
74
v8::Local<v8::Object> module = Nan::New<v8::Object>();
5+
86
v8::Local<v8::Object> alg = Nan::New<v8::Object>();
97
FF_SET_JS_PROP(alg, REGULAR, Nan::New<v8::Integer>(0));
108
FF_SET_JS_PROP(alg, LMEDS, Nan::New<v8::Integer>(cv::LMEDS));
119
FF_SET_JS_PROP(alg, RANSAC, Nan::New<v8::Integer>(cv::RANSAC));
1210
FF_SET_JS_PROP(alg, RHO, Nan::New<v8::Integer>(cv::RHO));
1311
module->Set(FF_V8STRING("robustnessAlgorithm"), alg);
12+
1413
Nan::SetMethod(module, "findHomography", FindHomography);
14+
1515
target->Set(Nan::New("calib3d").ToLocalChecked(), module);
1616
};
1717

1818
NAN_METHOD(Calib3d::FindHomography) {
1919
if (!info[0]->IsObject()) {
2020
// TODO usage messages
21-
return Nan::ThrowError(FF_V8STRING("findHomography - empty args object"));
21+
return Nan::ThrowError(FF_V8STRING("findHomography - args object required"));
2222
}
2323
v8::Local<v8::Object> args = info[0]->ToObject();
2424

25-
std::vector<cv::Point2d> srcPoints = Point::unpackJSPoint2Array(v8::Local<v8::Array>::Cast(FF::getCheckedJsProp(args, "srcPoints")));
26-
std::vector<cv::Point2d> dstPoints = Point::unpackJSPoint2Array(v8::Local<v8::Array>::Cast(FF::getCheckedJsProp(args, "dstPoints")));
25+
v8::Local<v8::Object> jsSrcPoints, jsDstPoints;
26+
std::vector<cv::Point2d> srcPoints, dstPoints;
27+
FF_GET_JSPROP_REQUIRED(args, jsSrcPoints, srcPoints, ToObject)
28+
FF_GET_JSPROP_REQUIRED(args, jsDstPoints, dstPoints, ToObject)
29+
Nan::TryCatch tryCatch;
30+
Point::unpackJSPoint2Array(srcPoints, v8::Local<v8::Array>::Cast(jsSrcPoints));
31+
Point::unpackJSPoint2Array(dstPoints, v8::Local<v8::Array>::Cast(jsDstPoints));
32+
if (tryCatch.HasCaught()) {
33+
return info.GetReturnValue().Set(tryCatch.ReThrow());
34+
}
2735
int method = 0;
2836
double ransacReprojThreshold = 3;
2937
cv::OutputArray mask = cv::noArray();
@@ -35,11 +43,14 @@ NAN_METHOD(Calib3d::FindHomography) {
3543
FF_DESTRUCTURE_TYPECHECKED_JSPROP_IFDEF(args, confidence, IsNumber, NumberValue)
3644

3745
if (args->HasOwnProperty(FF_V8STRING("mask"))) {
38-
Nan::ObjectWrap::Unwrap<Mat>(FF_GET_JSPROP(args, mask))->mat.copyTo(mask);
46+
Nan::ObjectWrap::Unwrap<Mat>(FF_GET_JSPROP(args, mask)->ToObject())->mat.copyTo(mask);
3947
}
4048

4149
cv::Mat homography;
42-
FF_TRY(homography = cv::findHomography(srcPoints, dstPoints, method, ransacReprojThreshold, mask, maxIters, confidence);)
50+
FF_TRY_CATCH(homography = cv::findHomography(srcPoints, dstPoints, method, ransacReprojThreshold, mask, maxIters, confidence);)
51+
if (tryCatch.HasCaught()) {
52+
return info.GetReturnValue().Set(tryCatch.ReThrow());
53+
}
4354
v8::Local<v8::Object> jsMat = Nan::NewInstance(Nan::New(Mat::constructor)->GetFunction()).ToLocalChecked();
4455
Nan::ObjectWrap::Unwrap<Mat>(jsMat)->setNativeProps(homography);
4556
info.GetReturnValue().Set(jsMat);

‎cc/modules/imgproc/imgproc.cc

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "imgproc.h"
2+
3+
NAN_MODULE_INIT(Imgproc::Init) {
4+
v8::Local<v8::Object> module = Nan::New<v8::Object>();
5+
6+
v8::Local<v8::Object> borderTypes = Nan::New<v8::Object>();
7+
FF_SET_JS_PROP(borderTypes, BORDER_CONSTANT, Nan::New<v8::Integer>(cv::BORDER_CONSTANT));
8+
FF_SET_JS_PROP(borderTypes, BORDER_REPLICATE, Nan::New<v8::Integer>(cv::BORDER_REPLICATE));
9+
FF_SET_JS_PROP(borderTypes, BORDER_REFLECT, Nan::New<v8::Integer>(cv::BORDER_REFLECT));
10+
FF_SET_JS_PROP(borderTypes, BORDER_WRAP, Nan::New<v8::Integer>(cv::BORDER_WRAP));
11+
FF_SET_JS_PROP(borderTypes, BORDER_REFLECT_101, Nan::New<v8::Integer>(cv::BORDER_REFLECT_101));
12+
FF_SET_JS_PROP(borderTypes, BORDER_TRANSPARENT, Nan::New<v8::Integer>(cv::BORDER_TRANSPARENT));
13+
FF_SET_JS_PROP(borderTypes, BORDER_ISOLATED, Nan::New<v8::Integer>(cv::BORDER_ISOLATED));
14+
FF_SET_JS_PROP(borderTypes, BORDER_DEFAULT, Nan::New<v8::Integer>(cv::BORDER_DEFAULT));
15+
module->Set(FF_V8STRING("borderTypes"), borderTypes);
16+
17+
v8::Local<v8::Object> interpolationFlags = Nan::New<v8::Object>();
18+
FF_SET_JS_PROP(borderTypes, INTER_NEAREST, Nan::New<v8::Integer>(cv::INTER_NEAREST));
19+
FF_SET_JS_PROP(borderTypes, INTER_LINEAR, Nan::New<v8::Integer>(cv::INTER_LINEAR));
20+
FF_SET_JS_PROP(borderTypes, INTER_CUBIC, Nan::New<v8::Integer>(cv::INTER_CUBIC));
21+
FF_SET_JS_PROP(borderTypes, INTER_AREA, Nan::New<v8::Integer>(cv::INTER_AREA));
22+
FF_SET_JS_PROP(borderTypes, INTER_LANCZOS4, Nan::New<v8::Integer>(cv::INTER_LANCZOS4));
23+
FF_SET_JS_PROP(borderTypes, INTER_MAX, Nan::New<v8::Integer>(cv::INTER_MAX));
24+
FF_SET_JS_PROP(borderTypes, WARP_FILL_OUTLIERS, Nan::New<v8::Integer>(cv::WARP_FILL_OUTLIERS));
25+
FF_SET_JS_PROP(borderTypes, WARP_INVERSE_MAP, Nan::New<v8::Integer>(cv::WARP_INVERSE_MAP));
26+
module->Set(FF_V8STRING("interpolationFlags"), borderTypes);
27+
28+
target->Set(Nan::New("imgproc").ToLocalChecked(), module);
29+
};

0 commit comments

Comments
 (0)