AIRLegend / aitrack

6DoF Head tracking software
MIT License
1.03k stars 102 forks source link

Losing tracking at distances approx > 2 meters (v0.6.6 and v0.7.0) #173

Open searching46dof opened 1 year ago

searching46dof commented 1 year ago

Describe the bug A clear and concise description of what the bug is. Losing tracking at distances approx > 2 meters (v0.6.6 and v0.7.0)

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error Test face tracking at varying distances to the camera (e.g. 1meter, 2meters, 3, meters, 4 meters, etc) Recent versions are losing face tracking very often at longer distances.

Expected behavior A clear and concise description of what you expected to happen. The symptom is not reproducible on version 0.6.5

Screenshots If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

Additional context Add any other context about the problem here. In StandardTracker::proc_face_detect, the rectangle returned in face is enlarged by 0.1x. This works for faces at approximately 1 meter since the face is much larger. For longer distances (e.g. 2 - 4 meters) the scaling factor needs to be adjusted (e.g. 0.4x for up to 4 meters)

searching46dof commented 1 year ago

This symptom is still occurring for version 0.7.1

searching46dof commented 1 year ago

A simpler way to fix this may be to use the existing scaling factor 0.1x to enlarge the rectangle. But the 0.1x number of pixels should not be less than a minumum number of pixels.

searching46dof commented 1 year ago

Trying to commit the following to fix this issue but having problems due to conflicts. This was tested and working for ranges of 4 to 5 meters

void Tracker::proc_face_detect(float* face, float width, float height) { float x = face[0]; float y = face[1]; float w = face[2]; float h = face[3];

/* Need to increase boundary by 10% for yaw, pitch and roll but boundary needs a minimum number of pixels for faces at longer distances which are smaller */
int additional_width_margin = (int)(w * 0.1f);
int additional_height_margin = (int)(h * 0.1f);
int minimum_width_margin = (int)width / (4 * 10); 
int minimum_height_margin = (int)height / (4 * 10); 
if (additional_width_margin < minimum_width_margin)
   additional_width_margin = minimum_width_margin;
if (additional_height_margin < minimum_height_margin) 
   additional_height_margin = minimum_height_margin;

int crop_x1 = (int)(x - additional_width_margin);
int crop_y1 = (int)(y - additional_height_margin);
int crop_x2 = (int)(x + w + additional_width_margin);
int crop_y2 = (int)(y + h + additional_height_margin); // force a little taller BB so the chin tends to be covered

face[0] = (float)std::max(0, crop_x1);
face[1] = (float)std::max(0, crop_y1);
face[2] = (float)std::min((int)width, crop_x2);
face[3] = (float)std::min((int)height, crop_y2);

}