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

Commit 27614dc

Browse files
committed
src: add some APIs so that we could setup EAST demo
Including: `Net.forward()` support more args; `cv.blobFromImage()` support more args; `Mat.at()` support more args; `cv.NMSBoxes()` new api. This commit also includes an example of EAST text detection.
1 parent b97d024 commit 27614dc

File tree

14 files changed

+301
-30
lines changed

14 files changed

+301
-30
lines changed

cc/core/Mat.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,22 @@ NAN_METHOD(Mat::FlattenFloat) {
226226

227227
NAN_METHOD(Mat::At) {
228228
FF_METHOD_CONTEXT("Mat::At");
229+
229230
cv::Mat matSelf = FF_UNWRAP_MAT_AND_GET(info.This());
230-
FF_ASSERT_INDEX_RANGE(info[0]->Int32Value(), matSelf.size[0] - 1, "Mat::At row");
231-
FF_ASSERT_INDEX_RANGE(info[1]->Int32Value(), matSelf.size[1] - 1, "Mat::At col");
232231
v8::Local<v8::Value> val;
233-
FF_MAT_APPLY_TYPED_OPERATOR(matSelf, val, matSelf.type(), FF_MAT_AT, FF::matGet);
234232
v8::Local<v8::Value> jsVal;
233+
234+
if (FF_IS_ARRAY(info[0])) {
235+
if ((long)FF_CAST_ARRAY(info[0])->Length() != matSelf.dims) {
236+
FF_THROW("expected array length to be equal to the dims");
237+
}
238+
FF_MAT_APPLY_TYPED_OPERATOR(matSelf, val, matSelf.type(), FF_MAT_AT_ARRAY, FF::matGet);
239+
} else {
240+
FF_ASSERT_INDEX_RANGE(info[0]->Int32Value(), matSelf.size[0] - 1, "Mat::At row");
241+
FF_ASSERT_INDEX_RANGE(info[1]->Int32Value(), matSelf.size[1] - 1, "Mat::At col");
242+
FF_MAT_APPLY_TYPED_OPERATOR(matSelf, val, matSelf.type(), FF_MAT_AT, FF::matGet);
243+
}
244+
235245
if (val->IsArray()) {
236246
FF_ARR vec = FF_ARR::Cast(val);
237247
FF_OBJ jsVec;

cc/core/matUtils.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
else \
1111
val = get(mat, info[0]->Int32Value(), info[1]->Int32Value());
1212

13+
#define FF_MAT_AT_ARRAY(mat, val, get) \
14+
{ \
15+
FF_ARG_UNPACK_INT_ARRAY(0, vec); \
16+
const int* idx = &vec.front(); \
17+
val = get(mat, idx); \
18+
}
19+
1320
#define FF_MAT_SET(mat, val, put) \
1421
if (mat.dims > 2) \
1522
put(mat, val, info[0]->Int32Value(), info[1]->Int32Value(), info[2]->Int32Value()); \
@@ -232,6 +239,11 @@ namespace FF {
232239
return Nan::New(mat.at<type>(r, c, z));
233240
}
234241

242+
template<typename type>
243+
static inline v8::Local<v8::Value> matGetVal(cv::Mat mat, const int* idx) {
244+
return Nan::New(mat.at<type>(idx));
245+
}
246+
235247
template<typename type>
236248
static inline v8::Local<v8::Value> matGetVec2(cv::Mat mat, int r, int c) {
237249
v8::Local<v8::Array> vec = Nan::New<v8::Array>(2);
@@ -248,6 +260,14 @@ namespace FF {
248260
return vec;
249261
}
250262

263+
template<typename type>
264+
static inline v8::Local<v8::Value> matGetVec2(cv::Mat mat, const int* idx) {
265+
v8::Local<v8::Array> vec = Nan::New<v8::Array>(2);
266+
vec->Set(0, Nan::New(mat.at< cv::Vec<type, 2> >(idx)[0]));
267+
vec->Set(1, Nan::New(mat.at< cv::Vec<type, 2> >(idx)[1]));
268+
return vec;
269+
}
270+
251271
template<typename type>
252272
static inline v8::Local<v8::Value> matGetVec3(cv::Mat mat, int r, int c) {
253273
v8::Local<v8::Array> vec = Nan::New<v8::Array>(3);
@@ -266,6 +286,15 @@ namespace FF {
266286
return vec;
267287
}
268288

289+
template<typename type>
290+
static inline v8::Local<v8::Value> matGetVec3(cv::Mat mat, const int* idx) {
291+
v8::Local<v8::Array> vec = Nan::New<v8::Array>(3);
292+
vec->Set(0, Nan::New(mat.at< cv::Vec<type, 3> >(idx)[0]));
293+
vec->Set(1, Nan::New(mat.at< cv::Vec<type, 3> >(idx)[1]));
294+
vec->Set(2, Nan::New(mat.at< cv::Vec<type, 3> >(idx)[2]));
295+
return vec;
296+
}
297+
269298
template<typename type>
270299
static inline v8::Local<v8::Value> matGetVec4(cv::Mat mat, int r, int c) {
271300
v8::Local<v8::Array> vec = Nan::New<v8::Array>(4);
@@ -285,6 +314,16 @@ namespace FF {
285314
vec->Set(3, Nan::New(mat.at< cv::Vec<type, 4> >(r, c, z)[3]));
286315
return vec;
287316
}
317+
318+
template<typename type>
319+
static inline v8::Local<v8::Value> matGetVec4(cv::Mat mat, const int* idx) {
320+
v8::Local<v8::Array> vec = Nan::New<v8::Array>(4);
321+
vec->Set(0, Nan::New(mat.at< cv::Vec<type, 4> >(idx)[0]));
322+
vec->Set(1, Nan::New(mat.at< cv::Vec<type, 4> >(idx)[1]));
323+
vec->Set(2, Nan::New(mat.at< cv::Vec<type, 4> >(idx)[2]));
324+
vec->Set(3, Nan::New(mat.at< cv::Vec<type, 4> >(idx)[3]));
325+
return vec;
326+
}
288327
}
289328

290-
#endif
329+
#endif

cc/cvTypes/matTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,4 @@ static void initMatTypes(v8::Local<v8::Object> module) {
5252
FF_MAT_TYPE(CV_64FC4);
5353
}
5454

55-
#endif
55+
#endif

cc/modules/dnn/NetBindings.h

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,57 +11,74 @@ namespace NetBindings {
1111
SetInputWorker(cv::dnn::Net self) {
1212
this->self = self;
1313
}
14-
14+
1515
cv::Mat blob;
1616
std::string name = "";
17-
18-
17+
18+
1919
std::string executeCatchCvExceptionWorker() {
2020
self.setInput(blob, name);
2121
return "";
2222
}
23-
23+
2424
bool unwrapRequiredArgs(Nan::NAN_METHOD_ARGS_TYPE info) {
2525
return (
2626
Mat::Converter::arg(0, &blob, info)
2727
);
2828
}
29-
29+
3030
bool unwrapOptionalArgs(Nan::NAN_METHOD_ARGS_TYPE info) {
3131
return (
3232
StringConverter::optArg(1, &name, info)
3333
);
3434
}
3535
};
36-
36+
3737
struct ForwardWorker : public CatchCvExceptionWorker {
3838
public:
3939
cv::dnn::Net self;
4040
ForwardWorker(cv::dnn::Net self) {
4141
this->self = self;
4242
}
43-
43+
4444
std::string outputName = "";
45-
45+
std::vector<std::string> outBlobNames;
46+
std::vector<cv::Mat> outputBlobs;
47+
4648
cv::Mat returnValue;
47-
49+
4850
std::string executeCatchCvExceptionWorker() {
49-
returnValue = self.forward(outputName);
51+
if (outBlobNames.size() > 0) {
52+
std::vector<cv::String> strings(
53+
outBlobNames.begin(),
54+
outBlobNames.end());
55+
self.forward(outputBlobs, strings);
56+
} else {
57+
returnValue = self.forward(outputName);
58+
}
5059
return "";
5160
}
52-
61+
5362
v8::Local<v8::Value> getReturnValue() {
63+
if (outBlobNames.size() > 0) {
64+
return ObjectArrayConverter<Mat, cv::Mat>::wrap(outputBlobs);
65+
}
66+
5467
return Mat::Converter::wrap(returnValue);
5568
}
56-
69+
5770
bool unwrapOptionalArgs(Nan::NAN_METHOD_ARGS_TYPE info) {
71+
if (FF_IS_ARRAY(info[0])) {
72+
return StringArrayConverter::optArg(0, &outBlobNames, info);
73+
}
74+
5875
return (
5976
StringConverter::optArg(0, &outputName, info)
6077
);
6178
}
6279
};
63-
80+
6481

6582
}
6683

67-
#endif
84+
#endif

cc/modules/dnn/dnn.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ NAN_MODULE_INIT(Dnn::Init) {
1919
Nan::SetMethod(target, "blobFromImageAsync", BlobFromImageAsync);
2020
Nan::SetMethod(target, "blobFromImages", BlobFromImages);
2121
Nan::SetMethod(target, "blobFromImagesAsync", BlobFromImagesAsync);
22+
Nan::SetMethod(target, "NMSBoxes", NMSBoxes);
2223
};
2324

2425
NAN_METHOD(Dnn::ReadNetFromTensorflow) {
@@ -85,4 +86,12 @@ NAN_METHOD(Dnn::BlobFromImagesAsync) {
8586
);
8687
}
8788

88-
#endif
89+
NAN_METHOD(Dnn::NMSBoxes) {
90+
FF::SyncBinding(
91+
std::make_shared<DnnBindings::NMSBoxes>(),
92+
"NMSBoxes",
93+
info
94+
);
95+
}
96+
97+
#endif

cc/modules/dnn/dnn.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Dnn {
1919
static NAN_METHOD(BlobFromImageAsync);
2020
static NAN_METHOD(BlobFromImages);
2121
static NAN_METHOD(BlobFromImagesAsync);
22+
static NAN_METHOD(NMSBoxes);
2223
};
2324

24-
#endif
25+
#endif

cc/modules/dnn/dnnBindings.h

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,17 @@ namespace DnnBindings {
7575
cv::Size2d size = cv::Size2d();
7676
cv::Vec3d mean = cv::Vec3d();
7777
bool swapRB = true;
78+
bool crop = true;
79+
int ddepth = CV_32F;
7880

7981
cv::Mat returnValue;
8082

8183
std::string executeCatchCvExceptionWorker() {
8284
if (isSingleImage) {
83-
returnValue = cv::dnn::blobFromImage(image, scalefactor, size, mean, swapRB);
85+
returnValue = cv::dnn::blobFromImage(image, scalefactor, size, mean, swapRB, crop, ddepth);
8486
}
8587
else {
86-
returnValue = cv::dnn::blobFromImages(images, scalefactor, size, mean, swapRB);
88+
returnValue = cv::dnn::blobFromImages(images, scalefactor, size, mean, swapRB, crop, ddepth);
8789
}
8890
return "";
8991
}
@@ -104,7 +106,9 @@ namespace DnnBindings {
104106
DoubleConverter::optArg(1, &scalefactor, info) ||
105107
Size::Converter::optArg(2, &size, info) ||
106108
Vec3::Converter::optArg(3, &mean, info) ||
107-
BoolConverter::optArg(4, &swapRB, info)
109+
BoolConverter::optArg(4, &swapRB, info) ||
110+
BoolConverter::optArg(5, &crop, info) ||
111+
IntConverter::optArg(6, &ddepth, info)
108112
);
109113
}
110114

@@ -118,12 +122,40 @@ namespace DnnBindings {
118122
DoubleConverter::optProp(&scalefactor, "scalefactor", opts) ||
119123
BoolConverter::optProp(&swapRB, "swapRB", opts) ||
120124
Size::Converter::optProp(&size, "size", opts) ||
121-
Vec3::Converter::optProp(&mean, "mean", opts)
125+
Vec3::Converter::optProp(&mean, "mean", opts) ||
126+
BoolConverter::optProp(&crop, "crop", opts) ||
127+
IntConverter::optProp(&ddepth, "ddepth", opts)
122128
);
123129
}
124130
};
125131

132+
struct NMSBoxes : public CatchCvExceptionWorker {
133+
public:
134+
std::vector<cv::Rect> bboxes;
135+
std::vector<float> scores;
136+
float score_threshold;
137+
float nms_threshold;
138+
std::vector<int> indices;
126139

140+
std::string executeCatchCvExceptionWorker() {
141+
cv::dnn::NMSBoxes(bboxes, scores, score_threshold,
142+
nms_threshold, indices);
143+
return "";
144+
}
145+
146+
v8::Local<v8::Value> getReturnValue() {
147+
return IntArrayConverter::wrap(indices);
148+
}
149+
150+
bool unwrapRequiredArgs(Nan::NAN_METHOD_ARGS_TYPE info) {
151+
return (
152+
ObjectArrayConverter<Rect, cv::Rect>::arg(0, &bboxes, info) ||
153+
FloatArrayConverter::arg(1, &scores, info) ||
154+
FloatConverter::arg(2, &score_threshold, info) ||
155+
FloatConverter::arg(3, &nms_threshold, info)
156+
);
157+
}
158+
};
127159
}
128160

129161
#endif

data/text-data/detection.png

284 KB
Loading

0 commit comments

Comments
 (0)