Skip to content

Commit

Permalink
Add center weighted face detection to version 0.6.6 using cv::FaceDet…
Browse files Browse the repository at this point in the history
…ectorYN

cv::FaceDetectorYN::>detect returns a matrix of faces where  get_distance_squared will return the row that is closest to the center of the preview window.
center_weighted should be made configurable since center weighted detection may not be desired under all circumstances.
  • Loading branch information
searching46dof committed Aug 28, 2022
1 parent bc847f9 commit 943aeae
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
54 changes: 48 additions & 6 deletions AITracker/src/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Tracker::Tracker(std::unique_ptr<PositionSolver>&& solver, std::wstring& detecti
session_lm = std::make_unique<Ort::Session>(*enviro, landmark_model_path.data(), session_options);

// Face detector
float score_threshold = .8;
float nms_threshold = .3;
float score_threshold = .8f;
float nms_threshold = .3f;
int topK = 50;
face_detector = cv::FaceDetectorYN::create(
std::string(detection_model_path.begin(), detection_model_path.end()),
Expand Down Expand Up @@ -82,6 +82,44 @@ float inline logit(float p)
return log(p) / 16.0f;
}

float Tracker::get_distance_squared(float x0, float y0, float x1, float y1)
{
// calculate distance squared.
// no need to for sqrt to obtain the smallest distance for optimization
float x_distance = (x1 - x0);
float y_distance = (y1 - y0);
float distance_squared = (x_distance * x_distance) + (y_distance * y_distance);
return distance_squared;
}

int Tracker::get_center_weighted_faces_row(const cv::Mat& image, const cv::Mat& faces)
{
// get center coordinates for image
float image_center_x = (float)(image.rows / 2);
float image_center_y = (float)(image.cols / 2);

float smallest_distance_squared = 0.0f;
int center_weighted_face_row = -1;
for (int row = 0; row < faces.rows; row++)
{
// get center coordinates for faces at row
float x0 = faces.at<float>(row, 0);
float y0 = faces.at<float>(row, 1);
float face_w = faces.at<float>(row, 2);
float face_h = faces.at<float>(row, 3);
float face_center_x = x0 + (face_w / 2);
float face_center_y = y0 + (face_h / 2);

float distance_squared = get_distance_squared(image_center_x, image_center_y, face_center_x, face_center_y);
if ((center_weighted_face_row == -1) || (distance_squared < smallest_distance_squared))
{
center_weighted_face_row = row;
smallest_distance_squared = distance_squared;
}
}
return center_weighted_face_row;
}

void Tracker::detect_face(const cv::Mat& image, FaceData& face_data)
{
cv::Mat resized, faces;
Expand All @@ -101,10 +139,14 @@ void Tracker::detect_face(const cv::Mat& image, FaceData& face_data)
if (faces.rows > 0)
{
face_data.face_detected = true;
float x0 = faces.at<float>(0, 0);
float y0 = faces.at<float>(0, 1);
float face_w = faces.at<float>(0, 2);
float face_h = faces.at<float>(0, 3);
int faces_row = 0;
bool center_weighted = true; // make center weighted face detection configurable
if (center_weighted)
faces_row = get_center_weighted_faces_row(image, faces);
float x0 = faces.at<float>(faces_row, 0);
float y0 = faces.at<float>(faces_row, 1);
float face_w = faces.at<float>(faces_row, 2);
float face_h = faces.at<float>(faces_row, 3);


float w_ratio = (width / im_width);
Expand Down
3 changes: 3 additions & 0 deletions AITracker/src/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ class Tracker
void proc_face_detect(float* face, float width = 1080, float height = 720);
void detect_landmarks(const cv::Mat& image, int x0, int y0, float scale_x, float scale_y, FaceData& face_data);
void proc_heatmaps(float* heatmaps, int x0, int y0, float scale_x, float scale_y, FaceData& face_data);

float get_distance_squared(float x0, float y0, float x1, float y1);
int get_center_weighted_faces_row(const cv::Mat& image, const cv::Mat& faces);
};

0 comments on commit 943aeae

Please sign in to comment.