人脸检测器FaceDetector
人脸检测 , seeta::FaceDetector 就是输入待检测的图片,输出检测到的每个人脸位置,用矩形表
示。
FaceDetector结果结构体
struct SeetaFaceInfo
{
SeetaRect pos;
float score;
};
struct SeetaFaceInfoArray
{
struct SeetaFaceInfo *data;
int size;
};
构造人脸检测器
seeta::v6::FaceDetector *Seetaface::faceDetector(int minFace)
{
if(minFace == 0)minFace = mPara.MinFaceSize;
if(!m_fd){
seeta::ModelSetting setting;
setting.append(mModelsPath.toStdString() + "face_detector.csta");
setting.set_device( seeta::ModelSetting::CPU );
setting.set_id(0);
m_fd = new seeta::FaceDetector(setting);
m_fd->set(seeta::FaceDetector::PROPERTY_MIN_FACE_SIZE, minFace);
m_fd->set(seeta::FaceDetector::PROPERTY_THRESHOLD, mPara.Fd_Threshold);
}
return m_fd;
}
检测人脸
auto faces = mSeetaface->faceDetector()->detect(image);
for(int i=0; i<faces.size; i++)
{
auto &face = faces.data[i].pos;
cv::rectangle( mat, cv::Rect( face.x, face.y, face.width, face.height ), color, 2, 8, 0 );
qout << "score = " << faces.data[i].score;
}
人脸跟踪模块 FaceTracker
人脸跟踪模块主要应用在视频中定位出图片中不同人脸的位置。利用返回的位置信息,使用opencv在图片中画出人脸位置方框
FaceTracker结果结构体
struct SeetaTrackingFaceInfo
{
SeetaRect pos;
float score; //识别分数
int frame_no;//内部调试保留字段,一般不使用
int PID; //区分不同人脸
int step; //内部调试保留字段,一般不使用
};struct SeetaTrackingFaceInfoArray
{
struct SeetaTrackingFaceInfo *data;
int size; //识别到人脸数量
};
PID 就是人员编号,如果跟踪分配了同一个 PID ,那么就可以认为相同 PID 的人脸属于同一个人。该功能主要是为了区分出视频中相同人脸,同一张图片一摸一样的人会被赋值不同的PID
构造人脸跟踪器
seeta::v6::FaceTracker *Seetaface::faceTracker(int w, int h, int minFace)
{
if(minFace == 0)minFace = mPara.MinFaceSize;
if(!m_tracker){
seeta::ModelSetting setting;
setting.append(mModelsPath.toStdString() + "face_detector.csta");
setting.set_device( seeta::ModelSetting::CPU );
setting.set_id(0);
m_tracker = new seeta::FaceTracker(setting, w, h);
m_tracker->SetMinFaceSize(minFace);
m_tracker->SetThreshold(mPara.Fd_Threshold);
m_tracker_w = w;
m_tracker_h = h;
m_tracker_minFace = minFace;
}
if((m_tracker_w != w) || (m_tracker_h != h)){
m_tracker_w = w;
m_tracker_h = h;
m_tracker->Reset();
m_tracker->SetVideoSize(w, h);
qout << w<<h;
}
if(m_tracker_minFace != minFace){
m_tracker_minFace = minFace;
m_tracker->SetVideoSize(w, h);
}
return m_tracker;
}
当检测逻辑断开,或者切换视频的时候(图片大小不一致时),就需要排除之前跟踪的逻辑,这个时候调用 Reset 方式清楚之前所有跟踪的结果,重新 PID 计数(文档是这样说的,实测并没有重新计数。需要修改源码如下图)。否则会出现人脸位置错误或代码溢出等问题
人脸追踪
auto faces = mSeetaface->faceTracker(image.width,image.height)->Track(image);
if( faces.size > 0 )
{
for(int i=0; i<faces.size; i++)
{
auto &face = faces.data[i].pos;
cv::rectangle( mat, cv::Rect( face.x, face.y, face.width, face.height ), color, 2, 8, 0 );
qout <<"PID = " << faces.data[i].PID << "score = " << faces.data[i].score;
}
}
这里处理先画出人脸后再进行适当缩放显示出图片