如何从 OpenCV 中的指针为 Android 创建 FaceRecognizer
How do I create a FaceRecognizer from a pointer in OpenCV for Android
我正在使用 OpenCV 2.4.10。
JNI - 训练面部识别
JNIEXPORT jlong JNICALL Java_com_sample_facialRecognition_DetectionBasedRecognition_nativeTrain
(JNIEnv * jenv, jstring pathIn)
{
vector<Mat> images;
vector<int> labels;
try {
std::string path;
std::string classlabel = "A";
GetJStringContent(jenv,pathIn,path);
if(!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
model->train(images, labels);
model.addref(); //don't let it self-destroy here..
FaceRecognizer * pf = model.obj;
return (jlong) pf;
}
catch (...)
{
return 0;
}
}
Java - 训练识别器
mNativeRecognition = nativeTrain(getFilesDir().toString());
Java - 进行检测和识别
nativeDetect(mGray, faces, mNativeRecognition);
JNI - 识别
JNIEXPORT jint JNICALL Java_com_sample_facialRecognition_DetectionBasedTracker_nativeDetect
(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces, jlong recog)
{
jint whoAreYou= 0;
try
{
vector<Rect> RectFaces;
((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray));
((DetectionBasedTracker*)thiz)->getObjects(RectFaces);
Ptr < FaceRecognizer > model = recog; //here is the problem
vector_Rect_to_Mat(RectFaces, *((Mat*)faces));
for (int i = 0; i < faces.size(); i++)
{
cv::Point pt1(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
cv::Point pt2(faces[i].x, faces[i].y);
cv::Rect face_i = faces[i];
cv::Mat face = grayscaleFrame(face_i);
cv::Mat face_resized;
cv::resize(face, face_resized, cv::Size(100, 120), 1.0, 1.0, INTER_CUBIC);
whoAreYou = model->predict(face_resized);
}
}
catch (...)
{
//catch...
}
return whoAreYou;
}
所以我试图从 nativeTrain 转换存储的指针,并在一个函数中实时使用它来检测和识别人脸。如何将该指针转换回 nativeDetect 中可用的 FaceRecognizer?
编辑:正如 berak 的评论,最好使用原始指针版本,否则您将需要使用 addref
保存对象。
如果仍然喜欢 cv::Ptr
版本,而不是 Ptr < FaceRecognizer > model = recog;
,我们应该给
Ptr < FaceRecognizer > model( (FaceRecognizer *)recog );
model->addref();
C++ 中的智能指针实现(std::shared_ptr
、std::unique_ptr
或弃用的 std::auto_ptr
),将不支持从原始指针到 赋值智能指针。请在此处查看旧的 cv::Ptr
实现(1). They also add an explicit
keyword(2)以防止从原始指针意外转换为智能指针。
注意:在 OpenCV 3.0 中,Ptr
class、obj
成员是私有的(3)并且 addref
方法被移除。所以这不适用于 3.0。还好奇为什么所有这些调用都是通过 JNI 进行的。没有 Java 包装器 ?
我正在使用 OpenCV 2.4.10。
JNI - 训练面部识别
JNIEXPORT jlong JNICALL Java_com_sample_facialRecognition_DetectionBasedRecognition_nativeTrain
(JNIEnv * jenv, jstring pathIn)
{
vector<Mat> images;
vector<int> labels;
try {
std::string path;
std::string classlabel = "A";
GetJStringContent(jenv,pathIn,path);
if(!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
model->train(images, labels);
model.addref(); //don't let it self-destroy here..
FaceRecognizer * pf = model.obj;
return (jlong) pf;
}
catch (...)
{
return 0;
}
}
Java - 训练识别器
mNativeRecognition = nativeTrain(getFilesDir().toString());
Java - 进行检测和识别
nativeDetect(mGray, faces, mNativeRecognition);
JNI - 识别
JNIEXPORT jint JNICALL Java_com_sample_facialRecognition_DetectionBasedTracker_nativeDetect
(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces, jlong recog)
{
jint whoAreYou= 0;
try
{
vector<Rect> RectFaces;
((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray));
((DetectionBasedTracker*)thiz)->getObjects(RectFaces);
Ptr < FaceRecognizer > model = recog; //here is the problem
vector_Rect_to_Mat(RectFaces, *((Mat*)faces));
for (int i = 0; i < faces.size(); i++)
{
cv::Point pt1(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
cv::Point pt2(faces[i].x, faces[i].y);
cv::Rect face_i = faces[i];
cv::Mat face = grayscaleFrame(face_i);
cv::Mat face_resized;
cv::resize(face, face_resized, cv::Size(100, 120), 1.0, 1.0, INTER_CUBIC);
whoAreYou = model->predict(face_resized);
}
}
catch (...)
{
//catch...
}
return whoAreYou;
}
所以我试图从 nativeTrain 转换存储的指针,并在一个函数中实时使用它来检测和识别人脸。如何将该指针转换回 nativeDetect 中可用的 FaceRecognizer?
编辑:正如 berak 的评论,最好使用原始指针版本,否则您将需要使用 addref
保存对象。
如果仍然喜欢 cv::Ptr
版本,而不是 Ptr < FaceRecognizer > model = recog;
,我们应该给
Ptr < FaceRecognizer > model( (FaceRecognizer *)recog );
model->addref();
C++ 中的智能指针实现(std::shared_ptr
、std::unique_ptr
或弃用的 std::auto_ptr
),将不支持从原始指针到 赋值智能指针。请在此处查看旧的 cv::Ptr
实现(1). They also add an explicit
keyword(2)以防止从原始指针意外转换为智能指针。
注意:在 OpenCV 3.0 中,Ptr
class、obj
成员是私有的(3)并且 addref
方法被移除。所以这不适用于 3.0。还好奇为什么所有这些调用都是通过 JNI 进行的。没有 Java 包装器 ?