double-hit-balls/windows/DoubleHitBalls-win/DoubleHitBalls-win/FaceLandmarkDetector.h

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);
};