112 lines
2.0 KiB
C++
Executable File
112 lines
2.0 KiB
C++
Executable File
#pragma once
|
|
|
|
#include <opencv2/core.hpp>
|
|
#include <opencv2/highgui.hpp>
|
|
#include <opencv2/imgproc.hpp>
|
|
#include <opencv2/calib3d.hpp>
|
|
|
|
#include <algorithm>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <chrono>
|
|
#include <iostream>
|
|
|
|
#include <opencv2/dnn.hpp>
|
|
|
|
#include <thread>
|
|
|
|
|
|
#include <queue>
|
|
#include <mutex>
|
|
#include <condition_variable>
|
|
|
|
|
|
#define USE_3D_LANDMARKS
|
|
|
|
|
|
//#include "boost/thread.hpp"
|
|
|
|
constexpr size_t LANDMARK_POINT_COUNT = 68;
|
|
|
|
constexpr size_t MAX_FACE_COUNT = 5;
|
|
|
|
|
|
struct FaceIntermediateStruct
|
|
{
|
|
bool valid = false;
|
|
|
|
cv::Rect faceRect;
|
|
cv::Mat faceFrame;
|
|
|
|
int frameIndex;
|
|
|
|
};
|
|
|
|
|
|
struct FaceLandmarkStruct
|
|
{
|
|
bool valid = false;
|
|
|
|
cv::Rect faceRect;
|
|
std::array<cv::Point2f, LANDMARK_POINT_COUNT> landmarkArr;
|
|
|
|
int frameIndex;
|
|
};
|
|
|
|
|
|
class FaceLandmarkDetector
|
|
{
|
|
public:
|
|
FaceLandmarkDetector();
|
|
~FaceLandmarkDetector();
|
|
|
|
void StartTrackProcess();
|
|
|
|
void StopTrackProcess();
|
|
|
|
std::array<FaceLandmarkStruct, MAX_FACE_COUNT> GetFaceLandmarks(cv::Mat frame, int frameIndex);
|
|
|
|
protected:
|
|
cv::dnn::Net faceNet;
|
|
|
|
std::array<cv::dnn::Net, MAX_FACE_COUNT> landmarkNetArr;
|
|
|
|
bool started = false;
|
|
|
|
|
|
//Sync variables - shared between threads:
|
|
|
|
cv::Mat syncLastFrame;
|
|
|
|
int syncLastFrameIndex;
|
|
|
|
std::array<FaceIntermediateStruct, MAX_FACE_COUNT> syncFaceRectArr;
|
|
|
|
std::array<FaceLandmarkStruct, MAX_FACE_COUNT> syncFaceLandmarkArr;
|
|
|
|
std::mutex syncMutex;
|
|
|
|
bool syncStop = false;
|
|
|
|
std::condition_variable syncFaceRectCond;
|
|
|
|
std::thread findFaceThread;
|
|
void FindFaceThreadProc();
|
|
|
|
std::array<std::thread, MAX_FACE_COUNT> landmarkThreadArr;
|
|
void FindLandmarkThreadProc(size_t threadIndex);
|
|
|
|
|
|
|
|
std::vector<cv::Rect> InnerFindFaces(cv::Mat frame);
|
|
|
|
cv::Mat InnerCutFaceFrame(cv::Mat frame, cv::Rect faceRect);
|
|
|
|
void InnerSeparateFacesToBuckets(std::vector<cv::Rect>& faceArr, std::vector<cv::Mat>& faceFrameArr, std::array<FaceIntermediateStruct, MAX_FACE_COUNT>& inOutBucketArr);
|
|
|
|
|
|
};
|
|
|