天天看点

seetaface6之画出人脸位置人脸检测器FaceDetector人脸跟踪模块 FaceTracker

人脸检测器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

seetaface6之画出人脸位置人脸检测器FaceDetector人脸跟踪模块 FaceTracker
seetaface6之画出人脸位置人脸检测器FaceDetector人脸跟踪模块 FaceTracker

 构造人脸跟踪器

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 计数(文档是这样说的,实测并没有重新计数。需要修改源码如下图)。否则会出现人脸位置错误或代码溢出等问题

seetaface6之画出人脸位置人脸检测器FaceDetector人脸跟踪模块 FaceTracker

人脸追踪

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;
        }
    }
           

这里处理先画出人脸后再进行适当缩放显示出图片

seetaface6之画出人脸位置人脸检测器FaceDetector人脸跟踪模块 FaceTracker