insightface进行视频中人脸识别
包含针对视频的简单人脸识别后续需增加阈值确定视频中的具体人防止跳振还需增加相关的release和接口等操作#includeiostream#includethread#includevector#includecondition_variable#includemutex#includeatomic#includeopencv4/opencv2/opencv.hpp#includeinspireface.hstd::mutex mtx;std::condition_variable face_cv;std::atomicboolface_cv_flag(false);structFrameTokenPair{cv::Mat frame;std::vectorHFFaceFeatureIdentityqueryFeatureIdentitys;std::vectorHFFaceFeaturequeryFeatures;};classThreadSafeTokenQueue{private:std::queueFrameTokenPairpairQueue;std::mutex mtx_;std::condition_variable cv_;std::atomicboolstop_flag_{false};constintmax_queue_size50;public:booladdFrameToken(cv::Matframe,std::vectorHFFaceFeaturequeryFeatures){std::lock_guardstd::mutexlock(mtx_);if(pairQueue.size()max_queue_size){std::cerrqueue is full, drop frame tokenstd::endl;returnfalse;}FrameTokenPair pair;pair.frameframe.clone();pair.queryFeaturesqueryFeatures;pairQueue.push(pair);cv_.notify_one();returntrue;}FrameTokenPairgetToken(){std::unique_lockstd::mutexlock(mtx_);cv_.wait(lock,[this](){return!pairQueue.empty();});if(pairQueue.empty()){std::cerrpairQueue为空gettoken失败std::endl;return{};}FrameTokenPair pairstd::move(pairQueue.front());pairQueue.pop();returnpair;}};boolcvMatToImageBitmap(constcv::Matmat,HFImageBitmapbitmap){if(mat.empty()){std::cerrempty framestd::endl;returnfalse;}cv::Mat bgr_mat;if(mat.channels()1){cv::cvtColor(mat,bgr_mat,cv::COLOR_GRAY2BGR);}elseif(mat.channels()4){cv::cvtColor(mat,bgr_mat,cv::COLOR_RGBA2BGR);}else{bgr_matmat;}HFImageBitmapData bitmapData{0};bitmapData.widthbgr_mat.cols;bitmapData.heightbgr_mat.rows;bitmapData.channelsbgr_mat.channels();bitmapData.databgr_mat.data;HResult retHFCreateImageBitmap(bitmapData,bitmap);if(ret!HSUCCEED){returnfalse;}returntrue;}intvideoDetectThread(ThreadSafeTokenQueuethreadSafeTokenQueue,conststd::string video_path){std::cout人脸检测线程开始std::endl;HResult ret;HPath packPath/home/yfzx/project/insightface/insightface/cpp-package/inspireface/test_res/pack/Megatron;retHFLaunchInspireFace(packPath);// 模型文件路径if(ret!HSUCCEED){HFLogPrint(HF_LOG_ERROR,Load Resource error: %d,ret);returnret;}HOption optionHF_ENABLE_QUALITY|HF_ENABLE_FACE_RECOGNITION;HFDetectMode detModeHF_DETECT_MODE_ALWAYS_DETECT;// 每次都重新检测所有人脸不追踪视频流有额外的模式HInt32 maxDetectNum20;HInt32 detectPixelLevel160;HFSession session;retHFCreateInspireFaceSessionOptional(option,detMode,maxDetectNum,detectPixelLevel,-1,session);if(ret!HSUCCEED){HFLogPrint(HF_LOG_ERROR,Create FaceContext error: %d,ret);returnret;}cv::VideoCapturecap(video_path);if(!cap.isOpened()){std::cerrfailed to open video filevideo_pathstd::endl;return-1;}intframe_widthstatic_castint(cap.get(cv::CAP_PROP_FRAME_WIDTH));intframe_heightstatic_castint(cap.get(cv::CAP_PROP_FRAME_HEIGHT));inttotal_framesstatic_castint(cap.get(cv::CAP_PROP_FRAME_COUNT));doublefpscap.get(cv::CAP_PROP_FPS);std::coutVideo info: frame_widthxframe_height, FPS: fps, Total frames: total_framesstd::endl;intframe_count0;cv::Mat frame;while(cap.read(frame)){// 1. 将opencv帧转为inspire face的image bitmapHFImageBitmap bitmap{0};if(!cvMatToImageBitmap(frame,bitmap)){frame_count;continue;}// 2. 创建图像流HFImageStream stream{0};retHFCreateImageStreamFromImageBitmap(bitmap,HF_CAMERA_ROTATION_0,stream);if(ret!HSUCCEED){std::cerrfailed to create image stream frameframe_countstd::endl;frame_count;continue;}// 3. 执行人脸识别// HFSession session {0};HFMultipleFaceData multipleFaceData{0};retHFExecuteFaceTrack(session,stream,multipleFaceData);if(ret!HSUCCEED){std::cerr检测人脸出错error coderetstd::endl;}std::vectorHFFaceFeaturequeryFeatures;if(multipleFaceData.detectedNum0){for(inti0;imultipleFaceData.detectedNum;i){// HFFaceFeature queryFeature;HFFaceFeature feature;retHFCreateFaceFeature(feature);if(ret!HSUCCEED){std::cout创建 face feature error :retstd::endl;}retHFFaceFeatureExtractTo(session,stream,multipleFaceData.tokens[i],feature);if(ret!HSUCCEED){HFLogPrint(HF_LOG_ERROR,Extract feature error: %d,ret);returnret;}// queryFeature.feature feature;// queryFeature.id -1;queryFeatures.push_back(feature);}threadSafeTokenQueue.addFrameToken(frame,queryFeatures);}else{continue;// 未检测到人脸}}std::cout读取frame完成std::endl;return1;}intfaceRecognitionThread(ThreadSafeTokenQueuethreadSafeTokenQueue,char*db_path../database/case_crud.db){HResult ret;// The resource file must be loaded before it can be usedretHFLaunchInspireFace(/home/yfzx/project/insightface/insightface/cpp-package/inspireface/test_res/pack/Megatron);// 模型文件路径if(ret!HSUCCEED){HFLogPrint(HF_LOG_ERROR,Load Resource error: %d,ret);returnret;}HFFeatureHubConfiguration featureHubConfig;featureHubConfig.primaryKeyModeHF_PK_AUTO_INCREMENT;// 自增IDfeatureHubConfig.enablePersistence1;// 持久化到DBfeatureHubConfig.persistenceDbPathdb_path;// db路径featureHubConfig.searchModeHF_SEARCH_MODE_EXHAUSTIVE;// 全量检索featureHubConfig.searchThreshold0.48f;// 匹配阈值retHFFeatureHubDataEnable(featureHubConfig);if(ret!HSUCCEED){HFLogPrint(HF_LOG_ERROR,Enable feature hub error: %d,ret);returnret;}HInt32 faceCount;retHFFeatureHubGetFaceCount(faceCount);std::cout人脸数据库中人脸数量为:faceCountstd::endl;HFloat confidence;while(true){FrameTokenPair tokenPairthreadSafeTokenQueue.getToken();for(inti0;itokenPair.queryFeatures.size();i){HFFaceFeatureIdentity searchedIdentity{0};// searchedIdentity.feature tokenPair.queryFeatures[i];// searchedIdentity.id -1;std::couttokenPair.queryFeatures[i].sizestd::endltokenPair.queryFeatures.data()std::endl;retHFFeatureHubFaceSearch(tokenPair.queryFeatures[i],confidence,searchedIdentity);if(ret!HSUCCEED){std::cerr查询数据库失败std::endl;continue;}std::cout查询到人脸人脸id为:searchedIdentity.idstd::endl;}}}intmain(){ThreadSafeTokenQueue threadSafeTokenQueue;std::string videopath../testdata/wyr.mp4;char*db_path../database/case_crud.db;std::threadt1(videoDetectThread,std::ref(threadSafeTokenQueue),videopath);std::threadt2(faceRecognitionThread,std::ref(threadSafeTokenQueue),db_path);t1.join();t2.join();return1;}