OpenCV 4.10.0
开源计算机视觉
|
在本教程中,您将学习如何
添加类标题
应该在新文件中将新算法的类标题添加到 include/opencv2/face 中。以下是可以用于集成新算法的模板,将 FacemarkNEW 更改为新算法的代表性名称,并使用相应的代表性文件名将其保存起来。
@code{.cpp} class CV_EXPORTS_W FacemarkNEW : public Facemark { public: struct CV_EXPORTS Config { Config(); /*read only parameters - just for example*/ double detect_thresh; //!< detection confidence threshold double sigma; //!< another parameter void read(const FileNode& /*fn*/); void write(FileStorage& /*fs*/) const; }; /*Builder and destructor*/ static Ptr<FacemarkNEW> create(const FacemarkNEW::Config &conf = FacemarkNEW::Config() ); virtual ~FacemarkNEW(){}; }; @endcode
添加实现代码
在源文件夹中使用代表新算法的名称创建一个新文件。以下是可以使用的模板。
@code{.cpp} #include "opencv2/face.hpp" #include "precomp.hpp" namespace cv { FacemarkNEW::Config::Config(){ detect_thresh = 0.5; sigma=0.2; } void FacemarkNEW::Config::read( const cv::FileNode& fn ){ *this = FacemarkNEW::Config(); if (!fn["detect_thresh"].empty()) fn["detect_thresh"] >> detect_thresh; if (!fn["sigma"].empty()) fn["sigma"] >> sigma; } void FacemarkNEW::Config::write( cv::FileStorage& fs ) const{ fs << "detect_thresh" << detect_thresh; fs << "sigma" << sigma; } /*implementation of the algorithm is in this class*/ class FacemarkNEWImpl : public FacemarkNEW { public: FacemarkNEWImpl( const FacemarkNEW::Config &conf = FacemarkNEW::Config() ); void read( const FileNode& /*fn*/ ); void write( FileStorage& /*fs*/ ) const; void loadModel(String filename); bool setFaceDetector(bool(*f)(InputArray , OutputArray, void * extra_params)); bool getFaces( InputArray image , OutputArray faces, void * extra_params); Config config; protected: bool addTrainingSample(InputArray image, InputArray landmarks); void training(); bool fit(InputArray image, InputArray faces, InputOutputArray landmarks, void * runtime_params); Config config; // configurations /*proxy to the user defined face detector function*/ bool(*faceDetector)(InputArray , OutputArray, void * ); }; // class Ptr<FacemarkNEW> FacemarkNEW::create(const FacemarkNEW::Config &conf){ return Ptr<FacemarkNEWImpl>(new FacemarkNEWImpl(conf)); } FacemarkNEWImpl::FacemarkNEWImpl( const FacemarkNEW::Config &conf ) : config( conf ) { // other initialization } bool FacemarkNEWImpl::addTrainingSample(InputArray image, InputArray landmarks){ // pre-process and save the new training sample return true; } void FacemarkNEWImpl::training(){ printf("training\n"); } bool FacemarkNEWImpl::fit( InputArray image, InputArray faces, InputOutputArray landmarks, void * runtime_params) { if(runtime_params!=0){ // do something based on the extra parameters } printf("fitting\n"); return 0; } void FacemarkNEWImpl::read( const cv::FileNode& fn ){ config.read( fn ); } void FacemarkNEWImpl::write( cv::FileStorage& fs ) const { config.write( fs ); } void FacemarkNEWImpl::loadModel(String filename){ // load the model } bool FacemarkNEWImpl::setFaceDetector(bool(*f)(InputArray , OutputArray, void * extra_params )){ faceDetector = f; isSetDetector = true; return true; } bool FacemarkNEWImpl::getFaces( InputArray image , OutputArray roi, void * extra_params){ if(!isSetDetector){ return false; } if(extra_params!=0){ //extract the extra parameters } std::vector<Rect> & faces = *(std::vector<Rect>*)roi.getObj(); faces.clear(); faceDetector(image.getMat(), faces, extra_params); return true; } } @endcode
编译代码
清除构建文件夹,然后重建整个库。请注意,您可以通过向 cmake 添加 "-D BUILD_opencv_<MODULE_NAME>=OFF" 标志来禁用其他供稿模块的编译。在此之后,可以在 "<build_folder>/modules/face" 中执行 make 命令来加快编译过程。
处理额外参数 要处理额外参数,应该创建一个新结构来容纳所有必需参数。以下是一个参数容器示例
以下是一个提取额外参数的代码段
以下是一个将额外参数传递到 fit 函数中的示例
为了理解这个原理,这里有一个简单的示例,您可以尝试编译它并查看其工作原理。