OpenCV3.3人臉識別模塊的API的變化
1. 前言
開始用最新版的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倉庫裏,人臉識別的頭文件夾下,已經是下面這樣:
一起期待吧。
知識星球
除了平時發文章之外,也會發一些平時學習過程中其他的參考資料和代碼,歡迎加入。