Files
DeepCamFaceSDK2.0/TEST/test_track/dtracker.cpp
2024-12-13 23:33:37 +08:00

171 lines
5.6 KiB
C++

/*************************************************************************
*
* DeepCam CONFIDENTIAL
* FILE: dtracker.cpp
*
* [2018] - [2019] DeepCam, LLC and DeepCam
NOTICE:
* All information contained herein is, and remains the property of DeepCam LLC.
* The intellectual and technical concepts contained herein are proprietary to DeepCam
* and may be covered by U.S. and Foreign Patents,patents in process, and are protected by
* trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* DeepCam, LLC.
*
*
* Written: Delong Qi
* Date: 17/12/2018
* Mail: delong.qi@deepcam.com
*/
#include "dtracker.h"
//#include "Inc/CenterFaceMnn.h"
#include "Inc/FaceQuality.h"
bool DTracker::check_edge(cv::Mat &image, cv::Rect &bbox, float ratio) {
if ((bbox.x - bbox.width / ratio) <= 0) return true;
if ((bbox.y - bbox.height / ratio) <= 0) return true;
if ((bbox.x + bbox.width + bbox.width / ratio) >= image.cols) return true;
if ((bbox.y + bbox.height + bbox.height / ratio) >= image.rows) return true;
return false;
}
float DTracker::IoU(const cv::Rect &boxA, const cv::Rect &boxB) {
cv::Rect rect2 = boxA | boxB;
cv::Rect rect3 = boxA & boxB;
float iou = rect3.area() * 1.0 / rect2.area();
return iou;
}
int DTracker::check_status() {
std::vector<int> fidsToDelete;
for (auto fid = 0; fid < faceTrackers.size(); fid++) {
if (faceTrackers[fid].frameCount != frameCount) {
faceTrackers[fid].quality -= 1;
if (faceTrackers[fid].quality < 0) faceTrackers[fid].quality = 0;
faceTrackers[fid].confidence -= 1;
if (faceTrackers[fid].confidence < 0) faceTrackers[fid].confidence = 0;
}
if (faceTrackers[fid].age > trackerAge) {
fidsToDelete.push_back(faceTrackers[fid].ID);
} else {
faceTrackers[fid].age += 1;
}
}
for (auto del = 0; del < fidsToDelete.size(); del++) {
for (auto fid = faceTrackers.begin(); fid != faceTrackers.end();) {
if (fidsToDelete[del] == fid->ID) {
int id = fid->ID;
faceTrackers.erase(fid);
//printf("Remove %d from faceTrackers.\n",id);
break;
}
fid++;
}
}
return 0;
}
int DTracker::detect(cv::Mat &image,float scale) {
if (image.empty()) {
printf("input image is empty.\n");
return -1;
}
std::vector<Anchor> allFaces = yoloV5_face_ncnn::getInstance()->Detect(image);
for (size_t i = 0; i < allFaces.size(); i++) {
int confidence = 0;
cv::Rect currFace = cv::Rect(cv::Point(allFaces[i].finalbox[0], allFaces[i].finalbox[1]), cv::Point(allFaces[i].finalbox[2], allFaces[i].finalbox[3]));
cv::Mat pose;
int quality = FaceQuality::GetInstance()->DetectQuality(image, currFace);
//int quality = (90 - std::max(abs(allFaces[i].rot_x), abs(allFaces[i].rot_y))) / 0.9;
//if (allFaces[i].bbox.height <= 80)
// confidence = allFaces[i].bbox.height * 0.375 + quality * 0.7;
//else confidence = quality * 0.7 + 30;
float hbox = allFaces[i].finalbox[3] - allFaces[i].finalbox[1];
if (hbox <= 80) {
confidence = hbox * 0.375 + quality * 0.7;
}
else
{
confidence = quality * 0.7 + 30;
}
int matchedFid = -1;
float matchedScore = 0.f;
for (auto fid = 0; fid < faceTrackers.size(); fid++) {
cv::Rect bbox = faceTrackers[fid].tbox;
float iou = IoU(bbox, currFace);
if (iou > matchedScore) {
matchedFid = fid;
matchedScore = iou;
}
}
if ((matchedFid >= 0) && (matchedScore >= 0.2)) {
int fid = matchedFid;
faceTrackers[fid].age = 0;
faceTrackers[fid].tbox = currFace;
faceTrackers[fid].quality = confidence;
faceTrackers[fid].confidence = confidence;
faceTrackers[fid].frameCount = frameCount;
//faceTrackers[fid].lmks = allFaces[i].lmk;
} else {
TrackerBox trackerBox;
trackerBox.age = 0;
trackerBox.ID = currFaceID;
trackerBox.tbox = currFace;
trackerBox.quality = confidence;
trackerBox.confidence = confidence;
trackerBox.frameCount = frameCount;
//trackerBox.lmks = allFaces[i].lmk;
faceTrackers.push_back(trackerBox);
currFaceID++;
}
}
return 0;
}
int DTracker::init(std::string face_model) {
currFaceID = 1;
frameCount = 0;
trackerAge = 10;
yoloV5_face_ncnn::getInstance()->loadModel(face_model);
//std::string model_path(face_model);
//mtcnn = new MTCNN(model_path);
//mtcnn->SetMinFace(min);
//mtcnn->SetNumThreads(thread_num);
return 0;
}
std::vector<TrackerBox> DTracker::track(cv::Mat &image,float scale) {
if (image.empty()) {
printf("input image is empty!\n");
return faceTrackers;
}
//LOGD("tracker image width : %d ,height : %d",image.cols,image.rows);
//long start = get_cur_time();
check_status();
//long end = get_cur_time();
//LOGD("check time %ld ms.\n", (end - start) / 1000);
//start = get_cur_time();
detect(image,scale);
//end = get_cur_time();
//LOGD("check time detect %ld ms.\n", (end - start) / 1000);
frameCount++;
return faceTrackers;
}
int DTracker::destroy() {
//delete mtcnn;
return 0;
}