前言
开始用最新版的OpenCV进行人脸识别的小伙伴也许已经发现了,人脸识别的最新API变化了。这也正是人脸识别等contrib模块没有放到主仓库的原因:不稳定,仍在开发中。当然这次的变化也预示着一些好的事情,毕竟自从OpenCV2.4时期人脸识别模块加入到OpenCV之后就几乎没怎么变过,这次变化说明又有人开始为OpenCV的人脸识别模块贡献代码了。而且还不仅于此,感兴趣的小伙伴可以去github看看OpenCV最新的人脸识别模块的代码,已经加入了人脸关键点检测、人脸对齐的内容,简直是非常让人期待!
其他的都是以后的事情,我们今天先看看人脸识别模块的变化,我们从facerec.hpp来看。
2. opencv3.3之前的facerec.hpp
(提示:代码可以左右滑动查看)
#ifndef __OPENCV_FACEREC_HPP__
#define __OPENCV_FACEREC_HPP__
#include "opencv2/face.hpp"
#include "opencv2/core.hpp"
namespace cv { namespace face {
// base for two classes
class CV_EXPORTS_W BasicFaceRecognizer : public FaceRecognizer
{
public:
/** @see setNumComponents */
CV_WRAP virtual int getNumComponents() const = 0;
// ----------- 此处省略代码若干行 -----------
// ----------- 此处省略代码若干行 ------------
// ----------- 此处省略代码若干行 -----------
CV_WRAP virtual cv::Mat getEigenValues() const = 0;
CV_WRAP virtual cv::Mat getEigenVectors() const = 0;
CV_WRAP virtual cv::Mat getMean() const = 0;
};
CV_EXPORTS_W Ptr<BasicFaceRecognizer> createEigenFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
CV_EXPORTS_W Ptr<BasicFaceRecognizer> createFisherFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
class CV_EXPORTS_W LBPHFaceRecognizer : public FaceRecognizer
{
public:
/** @see setGridX */
CV_WRAP virtual int getGridX() const = 0;
/** @copybrief getGridX @see getGridX */
CV_WRAP virtual void setGridX(int val) = 0;
// ----------- 此处省略代码若干行 -----------
// ----------- 此处省略代码若干行 ------------
// ----------- 此处省略代码若干行 -----------
CV_WRAP virtual cv::Mat getLabels() const = 0;
};
CV_EXPORTS_W Ptr<LBPHFaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold = DBL_MAX);
}} //namespace cv::face
#endif //__OPENCV_FACEREC_HPP__
这个文件里要注意的有:
第九行的那句注释:
// base for two classes
。说明BasicFaceRecognizer是两个类的基类:EigenFaceRecognizer和FisherFaceRecognizer。跟LBPHFaceRecognizer是没啥关系的。即使到了新的API中仍然是这样。第23、25、40行。创建三种人脸识别器的方法。大致如下,注意第三个和前两个的区别。
(提示:代码可以左右滑动查看)
Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer(); Ptr<BasicFaceRecognizer> model = createFisherFaceRecognizer(); Ptr<LBPHFaceRecognizer> model = createLBPHFaceRecognizer();
3. opencv3.3的facerec.hpp
(提示:代码可以左右滑动查看)
#ifndef __OPENCV_FACEREC_HPP__
#define __OPENCV_FACEREC_HPP__
#include "opencv2/face.hpp"
#include "opencv2/core.hpp"
namespace cv { namespace face {
// base for two classes
class CV_EXPORTS_W BasicFaceRecognizer : public FaceRecognizer
{
public:
/** @see setNumComponents */
CV_WRAP int getNumComponents() const;
// ----------- 此处省略代码若干行 -----------
// ----------- 此处省略代码若干行 ------------
// ----------- 此处省略代码若干行 -----------
CV_WRAP cv::Mat getEigenValues() const;
CV_WRAP cv::Mat getEigenVectors() const;
CV_WRAP cv::Mat getMean() const;
virtual void read(const FileNode& fn);
virtual void write(FileStorage& fs) const;
virtual bool empty() const;
using FaceRecognizer::read;
using FaceRecognizer::write;
protected:
int _num_components;
double _threshold;
std::vector<Mat> _projections;
Mat _labels;
Mat _eigenvectors;
Mat _eigenvalues;
Mat _mean;
};
class CV_EXPORTS_W EigenFaceRecognizer : public BasicFaceRecognizer
{
public:
CV_WRAP static Ptr<EigenFaceRecognizer> create(int num_components = 0, double threshold = DBL_MAX);
};
class CV_EXPORTS_W FisherFaceRecognizer : public BasicFaceRecognizer
{
public:
CV_WRAP static Ptr<FisherFaceRecognizer> create(int num_components = 0, double threshold = DBL_MAX);
};
class CV_EXPORTS_W LBPHFaceRecognizer : public FaceRecognizer
{
public:
/** @see setGridX */
CV_WRAP virtual int getGridX() const = 0;
// ----------- 此处省略代码若干行 -----------
// ----------- 此处省略代码若干行 ------------
// ----------- 此处省略代码若干行 -----------
CV_WRAP virtual cv::Mat getLabels() const = 0;
CV_WRAP static Ptr<LBPHFaceRecognizer> create(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold = DBL_MAX);
};
}} //namespace cv::face
#endif //__OPENCV_FACEREC_HPP__
我们对比同一个文件的不同时期的内容就可以看出一些变化了。首先需要注意的还是第九行的注释。前面说的同样适用。而且第二个文件的代码看起来更加清晰:EigenFaceRecognizer和FisherFaceRecognizer都是继承自BasicFaceRecognizer。然而LBPHFaceRecognizer跟BasicFaceRecognizer一样,都是继承自FaceRecognizer。
第二个是创建各人脸识别器的代码都同一变成了类的成员函数:create()
。所以我们创建人脸识别检测器的时候就要用下面这样的代码了。
(提示:代码可以左右滑动查看)
Ptr<EigenFaceRecognizer> model = EigenFaceRecognizer::create();
Ptr<FisherFaceRecognizer> model = FisherFaceRecognizer::create();
Ptr<LBPHFaceRecognizer> model = LBPHFaceRecognizer::create();
4. 以后的人脸识别模块
目前人脸识别模块头文件夹下只有以下三个文件:
bif.hpp facerec.hpp predict_collector.hpp
而现在最新的contrib仓库里,人脸识别的头文件夹下,已经是下面这样:
一起期待吧。
本文暂时没有评论,来添加一个吧(●'◡'●)