请详细解释下这段代码void FaceTracker::OnNewFaceData( const std::vector<human_sensing::CrosFace>& faces) { // Given |f1| and |f2| from two different (usually consecutive) frames, treat // the two rectangles as the same face if their position delta is less than // kFaceDistanceThresholdSquare. // // This is just a heuristic and is not accurate in some corner cases, but we // don't have face tracking. auto is_same_face = [&](const Rect<float>& f1, const Rect<float>& f2) -> bool { const float center_f1_x = f1.left + f1.width / 2; const float center_f1_y = f1.top + f1.height / 2; const float center_f2_x = f2.left + f2.width / 2; const float center_f2_y = f2.top + f2.height / 2; constexpr float kFaceDistanceThresholdSquare = 0.1 * 0.1; const float dist_square = std::pow(center_f1_x - center_f2_x, 2.0f) + std::pow(center_f1_y - center_f2_y, 2.0f); return dist_square < kFaceDistanceThresholdSquare; }; for (const auto& f : faces) { FaceState s = { .normalized_bounding_box = Rect<float>( f.bounding_box.x1 / options_.active_array_dimension.width, f.bounding_box.y1 / options_.active_array_dimension.height, (f.bounding_box.x2 - f.bounding_box.x1) / options_.active_array_dimension.width, (f.bounding_box.y2 - f.bounding_box.y1) / options_.active_array_dimension.height), .last_detected_ticks = base::TimeTicks::Now(), .has_attention = std::fabs(f.pan_angle) < options_.pan_angle_range}; bool found_matching_face = false; for (auto& known_face : faces_) { if (is_same_face(s.normalized_bounding_box, known_face.normalized_bounding_box)) { found_matching_face = true; if (!s.has_attention) { // If the face isn't looking at the camera, reset the timer. s.first_detected_ticks = base::TimeTicks::Max(); } else if (!known_face.has_attention && s.has_attention) { // If the face starts looking at the camera, start the timer. s.first_detected_ticks = base::TimeTicks::Now(); } else { s.first_detected_ticks = known_face.first_detected_ticks; } known_face = s; break; } } if (!found_matching_face) { s.first_detected_ticks = base::TimeTicks::Now(); faces_.push_back(s); } } // Flush expired face states. for (auto it = faces_.begin(); it != faces_.end();) { if (ElapsedTimeMs(it->last_detected_ticks) > options_.face_phase_out_threshold_ms) { it = faces_.erase(it); } else { ++it; } } }
时间: 2024-04-21 08:29:17 浏览: 100
这段代码是一个人脸追踪器的实现,输入参数是一个包含多个人脸信息的向量faces。该函数会对每个人脸进行处理,首先将人脸的位置和大小进行归一化,然后遍历已知人脸向量faces_,判断该人脸是否与已知人脸的位置相近,若相近则更新该已知人脸的状态,否则将该人脸加入已知人脸向量faces_。对于已知人脸的状态,如果人脸没有注视相机,则重置计时器;如果人脸开始注视相机,则开始计时;如果人脸一直注视相机,则更新计时器状态。最后,将已经过期的人脸状态从已知人脸向量faces_中删除。该代码实现了简单的人脸追踪与状态更新,但也存在一些不准确的情况,需要进一步改进。
相关问题
请详细解释下这段代码void FaceTracker::OnOptionsUpdated(const base::Value& json_values) { LoadIfExist(json_values, kFacePhaseInThresholdMs, &options_.face_phase_in_threshold_ms); LoadIfExist(json_values, kFacePhaseOutThresholdMs, &options_.face_phase_out_threshold_ms); LoadIfExist(json_values, kPanAngleRange, &options_.pan_angle_range); VLOGF(1) << "FaceTracker options:" << " face_phase_in_threshold_ms" << options_.face_phase_in_threshold_ms << " face_phase_out_threshold_ms=" << options_.face_phase_out_threshold_ms << " pan_angle_range=" << options_.pan_angle_range; }
这段代码是实现了一个人脸追踪器的参数更新函数,输入参数是一个json_values对象,包含了更新的参数信息。函数中通过调用LoadIfExist函数,将json_values对象中的三个参数 face_phase_in_threshold_ms、face_phase_out_threshold_ms、pan_angle_range 加载到 FaceTracker 类的 options_ 成员变量中。其中 face_phase_in_threshold_ms 是人脸进入追踪状态的时间阈值,face_phase_out_threshold_ms 是人脸离开追踪状态的时间阈值,pan_angle_range 是人脸注视相机的夹角范围。最后,该函数会输出调试信息,将更新后的参数值打印出来。这段代码实现了人脸追踪器的参数更新功能,可以通过更新参数来优化人脸追踪的效果。
请解释下这段代码namespace cros { // FaceTracker takes a set of face data produced by FaceDetector as input, // filters the input, and produces the bounding rectangle that encloses the // filtered input. class FaceTracker { public: struct Options { // The dimension of the active sensory array in pixels. Used for normalizing // the input face coordinates. Size active_array_dimension; // The dimension of the active stream that will be cropped. Used for // translating the ROI coordinates in the active array space. Size active_stream_dimension; // The threshold in ms for including a newly detected face for tracking. int face_phase_in_threshold_ms = 3000; // The threshold in ms for excluding a face that's no longer detected for // tracking. int face_phase_out_threshold_ms = 2000; // The angle range [|pan_angle_range|, -|pan_angle_range|] in degrees used // to determine if a face is looking at the camera. float pan_angle_range = 30.0f; }; explicit FaceTracker(const Options& options); ~FaceTracker() = default; FaceTracker(FaceTracker& other) = delete; FaceTracker& operator=(FaceTracker& other) = delete; // Callback for when new face data are ready. void OnNewFaceData(const std::vector<human_sensing::CrosFace>& faces); // The all the rectangles of all the detected faces. std::vector<Rect<float>> GetActiveFaceRectangles() const; // Gets the rectangle than encloses all the detected faces. Returns a // normalized rectangle in [0.0, 1.0] x [0.0, 1.0] with respect to the active // stream dimension. Rect<float> GetActiveBoundingRectangleOnActiveStream() const; void OnOptionsUpdated(const base::Value& json_values); private: struct FaceState { Rect<float> normalized_bounding_box = {0.0f, 0.0f, 0.0f, 0.0f}; base::TimeTicks first_detected_ticks; base::TimeTicks last_detected_ticks; bool has_attention = false; }; Options options_; std::vector<FaceState> faces_; }; } // namespace cros
这段代码定义了一个名为 "FaceTracker" 的类,用于对人脸数据进行过滤并生成边界框。该类具有一个嵌套的 "Options" 结构体,用于存储一些选项参数,例如输入坐标的维度、阈值等。类中还定义了一些函数,例如 "OnNewFaceData" 用于处理新的人脸数据, "GetActiveFaceRectangles" 返回所有检测到的人脸的矩形框, "GetActiveBoundingRectangleOnActiveStream" 返回包含所有检测到的人脸的矩形框。同时,它也包含了一些私有成员变量和结构体,例如 "FaceState" 结构体用于存储每个人脸的状态信息。
阅读全文