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

Commit 1cc4ac8

Browse files
Merge pull request justadudewhohacks#269 from nicholasc/facemark
Facemark API
2 parents 3608d5a + d7f4444 commit 1cc4ac8

26 files changed

+1206
-40
lines changed

binding.gyp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@
6666
"cc/modules/face/EigenFaceRecognizer.cc",
6767
"cc/modules/face/FisherFaceRecognizer.cc",
6868
"cc/modules/face/LBPHFaceRecognizer.cc",
69+
"cc/modules/face/Facemark.cc",
70+
"cc/modules/face/FacemarkAAM.cc",
71+
"cc/modules/face/FacemarkAAMData.cc",
72+
"cc/modules/face/FacemarkAAMParams.cc",
73+
"cc/modules/face/FacemarkLBF.cc",
74+
"cc/modules/face/FacemarkLBFParams.cc",
6975
"cc/modules/text/text.cc",
7076
"cc/modules/text/OCRHMMClassifier.cc",
7177
"cc/modules/text/OCRHMMDecoder.cc",

cc/macros.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99
#define FF_GETTER(clazz, name, prop) \
1010
NAN_GETTER(name) { info.GetReturnValue().Set(Nan::ObjectWrap::Unwrap<clazz>(info.This())->prop); }
1111

12+
#define FF_GETTER_SIMPLE(clazz, name, prop, converter) \
13+
NAN_GETTER(name) { \
14+
v8::Local<v8::Value> jsValue = converter::wrap( \
15+
Nan::ObjectWrap::Unwrap<clazz>(info.This())->prop \
16+
); \
17+
info.GetReturnValue().Set(jsValue); \
18+
}
19+
20+
#define FF_GETTER_COMPLEX(clazz, name, prop, converter) FF_GETTER_SIMPLE(clazz, name, prop, converter)
21+
1222
#define FF_GETTER_JSOBJ(clazz, name, value, unwrapper, ctor) \
1323
NAN_GETTER(name) { \
1424
v8::Local<v8::Object> jsObj = FF_NEW_INSTANCE(ctor); \
@@ -96,4 +106,20 @@ static FF_FUNC_TYPE ff_func = FF_FUNC_TYPE();
96106
#define FF_SETTER_NUMBER(clazz, name, prop) FF_SETTER(clazz, name, prop, ff_number)
97107
#define FF_SETTER_BOOL(clazz, name, prop) FF_SETTER(clazz, name, prop, ff_bool)
98108

99-
#endif
109+
#define FF_SETTER_SIMPLE(clazz, name, prop, converter) \
110+
NAN_SETTER(name##Set) { \
111+
FF_METHOD_CONTEXT(#name); \
112+
Nan::ObjectWrap::Unwrap<clazz>(info.This())->prop = converter::unwrap( \
113+
value \
114+
); \
115+
}
116+
117+
#define FF_SETTER_COMPLEX(clazz, name, prop, type, converter) \
118+
NAN_SETTER(name##Set) { \
119+
FF_METHOD_CONTEXT(#name); \
120+
type target; \
121+
converter::unwrap(&target, value); \
122+
Nan::ObjectWrap::Unwrap<clazz>(info.This())->prop = target; \
123+
}
124+
125+
#endif

cc/modules/face/Facemark.cc

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#ifdef HAVE_FACE
2+
3+
#include "Facemark.h"
4+
#include "FacemarkBindings.h"
5+
6+
#if CV_VERSION_MINOR >= 4
7+
8+
NAN_METHOD(Facemark::Save) {
9+
FF_METHOD_CONTEXT("Facemark::Save");
10+
FF_ARG_STRING(0, std::string path);
11+
FF_UNWRAP(info.This(), Facemark)->save(path);
12+
}
13+
14+
NAN_METHOD(Facemark::Load) {
15+
FF_METHOD_CONTEXT("Facemark::Load");
16+
FF_ARG_STRING(0, std::string path);
17+
FF_UNWRAP(info.This(), Facemark)->load(path);
18+
}
19+
20+
void Facemark::Init(v8::Local<v8::FunctionTemplate> ctor) {
21+
Nan::SetPrototypeMethod(ctor, "addTrainingSample", AddTrainingSample);
22+
Nan::SetPrototypeMethod(ctor, "addTrainingSampleAsync",
23+
AddTrainingSampleAsync);
24+
Nan::SetPrototypeMethod(ctor, "loadModel", LoadModel);
25+
Nan::SetPrototypeMethod(ctor, "loadModelAsync", LoadModelAsync);
26+
Nan::SetPrototypeMethod(ctor, "getData", GetData);
27+
Nan::SetPrototypeMethod(ctor, "getDataAsync", GetDataAsync);
28+
Nan::SetPrototypeMethod(ctor, "getFaces", GetFaces);
29+
Nan::SetPrototypeMethod(ctor, "getFacesAsync", GetFacesAsync);
30+
Nan::SetPrototypeMethod(ctor, "setFaceDetector", SetFaceDetector);
31+
Nan::SetPrototypeMethod(ctor, "training", Training);
32+
Nan::SetPrototypeMethod(ctor, "trainingAsync", TrainingAsync);
33+
Nan::SetPrototypeMethod(ctor, "fit", Fit);
34+
Nan::SetPrototypeMethod(ctor, "fitAsync", FitAsync);
35+
Nan::SetPrototypeMethod(ctor, "save", Save);
36+
Nan::SetPrototypeMethod(ctor, "load", Load);
37+
};
38+
39+
NAN_METHOD(Facemark::AddTrainingSample) {
40+
FF::SyncBinding(
41+
std::make_shared<FacemarkBindings::AddTrainingSampleWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
42+
"Facemark::AddTrainingSample",
43+
info
44+
);
45+
}
46+
47+
NAN_METHOD(Facemark::AddTrainingSampleAsync) {
48+
FF::AsyncBinding(
49+
std::make_shared<FacemarkBindings::AddTrainingSampleWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
50+
"Facemark::AddTrainingSampleAsync",
51+
info
52+
);
53+
}
54+
55+
NAN_METHOD(Facemark::LoadModel) {
56+
FF::SyncBinding(
57+
std::make_shared<FacemarkBindings::LoadModelWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
58+
"Facemark::LoadModel",
59+
info
60+
);
61+
}
62+
63+
NAN_METHOD(Facemark::LoadModelAsync) {
64+
FF::AsyncBinding(
65+
std::make_shared<FacemarkBindings::LoadModelWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
66+
"Facemark::LoadModelAsync",
67+
info
68+
);
69+
}
70+
71+
NAN_METHOD(Facemark::GetData) {
72+
FF::SyncBinding(
73+
std::make_shared<FacemarkBindings::GetDataWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
74+
"Facemark::GetData",
75+
info
76+
);
77+
}
78+
79+
NAN_METHOD(Facemark::GetDataAsync) {
80+
FF::AsyncBinding(
81+
std::make_shared<FacemarkBindings::GetDataWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
82+
"Facemark::GetDataAsync",
83+
info
84+
);
85+
}
86+
87+
NAN_METHOD(Facemark::GetFaces) {
88+
FF::SyncBinding(
89+
std::make_shared<FacemarkBindings::GetFacesWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
90+
"Facemark::GetFaces",
91+
info
92+
);
93+
}
94+
95+
NAN_METHOD(Facemark::GetFacesAsync) {
96+
FF::AsyncBinding(
97+
std::make_shared<FacemarkBindings::GetFacesWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
98+
"Facemark::GetFacesAsync",
99+
info
100+
);
101+
}
102+
103+
NAN_METHOD(Facemark::SetFaceDetector) {
104+
FF_METHOD_CONTEXT("SetFaceDetector");
105+
106+
if (!info[0]->IsFunction()) {
107+
return Nan::ThrowError(Nan::New("Facemark::SetFaceDetector - Error: "
108+
"expected argument 0 to be of type")
109+
.ToLocalChecked());
110+
}
111+
112+
FF_ARG_FUNC(0, v8::Local<v8::Function> cbFunc);
113+
Nan::Callback *callback = new Nan::Callback(cbFunc);
114+
115+
bool results = FF_UNWRAP(info.This(), Facemark)
116+
->getFacemark()
117+
->setFaceDetector((cv::face::FN_FaceDetector)detector, callback);
118+
119+
info.GetReturnValue().Set(Nan::New<v8::Boolean>(results));
120+
}
121+
122+
NAN_METHOD(Facemark::Training) {
123+
FF::SyncBinding(
124+
std::make_shared<FacemarkBindings::TrainingWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
125+
"Facemark::Train",
126+
info
127+
);
128+
}
129+
130+
NAN_METHOD(Facemark::TrainingAsync) {
131+
FF::AsyncBinding(
132+
std::make_shared<FacemarkBindings::TrainingWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
133+
"Facemark::TrainAsync",
134+
info
135+
);
136+
}
137+
138+
NAN_METHOD(Facemark::Fit) {
139+
FF::SyncBinding(
140+
std::make_shared<FacemarkBindings::FitWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
141+
"Facemark::Fit",
142+
info
143+
);
144+
}
145+
146+
NAN_METHOD(Facemark::FitAsync) {
147+
FF::AsyncBinding(
148+
std::make_shared<FacemarkBindings::FitWorker>(FF_UNWRAP(info.This(), Facemark)->getFacemark()),
149+
"Facemark::FitAsync",
150+
info
151+
);
152+
}
153+
154+
bool Facemark::detector(cv::InputArray image, cv::OutputArray faces,
155+
Nan::Callback *callback) {
156+
Nan::HandleScope scope;
157+
158+
cv::Mat frame = image.getMat().clone();
159+
v8::Local<v8::Value> jsMat = Mat::Converter::wrap(frame);
160+
161+
v8::Local<v8::Value> argv[] = {jsMat};
162+
FF_OBJ jsObject = callback->Call(1, argv)->ToObject();
163+
164+
std::vector<cv::Rect> _faces;
165+
ObjectArrayConverter<Rect, cv::Rect>::unwrap(&_faces, jsObject);
166+
167+
cv::Mat(_faces).copyTo(faces);
168+
169+
return true;
170+
}
171+
172+
#endif
173+
174+
#endif

cc/modules/face/Facemark.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "NativeNodeUtils.h"
2+
#include "Mat.h"
3+
#include "Point.h"
4+
#include "Rect.h"
5+
#include "macros.h"
6+
#include <iostream>
7+
#include <opencv2/face.hpp>
8+
9+
#if CV_VERSION_MINOR >= 4
10+
11+
#ifndef __FF_FACEMARK_H__
12+
#define __FF_FACEMARK_H__
13+
14+
class Facemark : public Nan::ObjectWrap {
15+
public:
16+
virtual cv::Ptr<cv::face::Facemark> getFacemark() = 0;
17+
virtual void save(std::string) = 0;
18+
virtual void load(std::string) = 0;
19+
20+
static void Init(v8::Local<v8::FunctionTemplate>);
21+
22+
static NAN_METHOD(AddTrainingSample);
23+
static NAN_METHOD(AddTrainingSampleAsync);
24+
static NAN_METHOD(LoadModel);
25+
static NAN_METHOD(LoadModelAsync);
26+
static NAN_METHOD(GetData);
27+
static NAN_METHOD(GetDataAsync);
28+
static NAN_METHOD(GetFaces);
29+
static NAN_METHOD(GetFacesAsync);
30+
static NAN_METHOD(SetFaceDetector);
31+
static NAN_METHOD(Training);
32+
static NAN_METHOD(TrainingAsync);
33+
static NAN_METHOD(Fit);
34+
static NAN_METHOD(FitAsync);
35+
static NAN_METHOD(Save);
36+
static NAN_METHOD(Load);
37+
38+
static bool detector(cv::InputArray image, cv::OutputArray faces,
39+
Nan::Callback *callback);
40+
};
41+
42+
#endif
43+
44+
#endif

cc/modules/face/FacemarkAAM.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifdef HAVE_FACE
2+
3+
#include "FacemarkAAM.h"
4+
#include "FacemarkAAMParams.h"
5+
6+
#if CV_VERSION_MINOR >= 4
7+
8+
Nan::Persistent<v8::FunctionTemplate> FacemarkAAM::constructor;
9+
10+
NAN_MODULE_INIT(FacemarkAAM::Init) {
11+
v8::Local<v8::FunctionTemplate> ctor =
12+
Nan::New<v8::FunctionTemplate>(FacemarkAAM::New);
13+
v8::Local<v8::ObjectTemplate> instanceTemplate = ctor->InstanceTemplate();
14+
15+
Facemark::Init(ctor);
16+
constructor.Reset(ctor);
17+
ctor->SetClassName(Nan::New("FacemarkAAM").ToLocalChecked());
18+
instanceTemplate->SetInternalFieldCount(1);
19+
20+
target->Set(Nan::New("FacemarkAAM").ToLocalChecked(), ctor->GetFunction());
21+
};
22+
23+
NAN_METHOD(FacemarkAAM::New) {
24+
FF_METHOD_CONTEXT("FacemarkAAM::New");
25+
26+
FF_ARG_INSTANCE_IFDEF(
27+
0,
28+
cv::face::FacemarkAAM::Params params,
29+
FacemarkAAMParams::constructor,
30+
FF_UNWRAP_FACEMARKAAMPARAMS_AND_GET,
31+
cv::face::FacemarkAAM::Params()
32+
);
33+
34+
FacemarkAAM *self = new FacemarkAAM();
35+
self->Wrap(info.Holder());
36+
self->facemark = cv::face::FacemarkAAM::create(params);
37+
38+
FF_RETURN(info.Holder());
39+
};
40+
41+
#endif
42+
43+
#endif

cc/modules/face/FacemarkAAM.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "Facemark.h"
2+
3+
#if CV_VERSION_MINOR >= 4
4+
5+
#ifndef __FF_FACEMARKAAM_H__
6+
#define __FF_FACEMARKAAM_H__
7+
8+
class FacemarkAAM : public Facemark {
9+
public:
10+
cv::Ptr<cv::face::Facemark> facemark;
11+
12+
void save(std::string path) { facemark->save(path); }
13+
14+
void load(std::string path) {
15+
cv::Algorithm::load<cv::face::FacemarkAAM>(path);
16+
}
17+
18+
static NAN_MODULE_INIT(Init);
19+
static NAN_METHOD(New);
20+
21+
static Nan::Persistent<v8::FunctionTemplate> constructor;
22+
cv::Ptr<cv::face::Facemark> getFacemark() { return facemark; }
23+
};
24+
25+
#endif
26+
27+
#endif

cc/modules/face/FacemarkAAMData.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifdef HAVE_FACE
2+
3+
#include "FacemarkAAMData.h"
4+
5+
#if CV_VERSION_MINOR >= 4
6+
7+
Nan::Persistent<v8::FunctionTemplate> FacemarkAAMData::constructor;
8+
9+
NAN_MODULE_INIT(FacemarkAAMData::Init) {
10+
v8::Local<v8::FunctionTemplate> ctor =
11+
Nan::New<v8::FunctionTemplate>(FacemarkAAMData::New);
12+
v8::Local<v8::ObjectTemplate> instanceTemplate = ctor->InstanceTemplate();
13+
14+
constructor.Reset(ctor);
15+
ctor->SetClassName(FF_NEW_STRING("FacemarkAAMData"));
16+
instanceTemplate->SetInternalFieldCount(1);
17+
18+
Nan::SetAccessor(instanceTemplate, FF_NEW_STRING("s0"), s0Get, s0Set);
19+
20+
target->Set(FF_NEW_STRING("FacemarkAAMData"), ctor->GetFunction());
21+
};
22+
23+
NAN_METHOD(FacemarkAAMData::New) {
24+
FF_METHOD_CONTEXT("FacemarkAAMData::New");
25+
FacemarkAAMData *self = new FacemarkAAMData();
26+
self->data = cv::face::FacemarkAAM::Data();
27+
self->Wrap(info.Holder());
28+
FF_RETURN(info.Holder());
29+
};
30+
31+
#endif
32+
33+
#endif

0 commit comments

Comments
 (0)