首页 > 解决方案 > 如何在 dlib 的 array2d 上从 dlib::rectangle 创建 cv::Mat图片?

问题描述

我使用 dlib 的 hog 检测器,因为它比 opencv haarcascades 发现人脸要好得多。但它无法检测到脸上的情绪(或者可以???)。我需要从 dlib::rectangle 中提取一个带有面部的“子图像”,并从中创建 cv::Mat 以调用预加载的“haarcascade_smile.xml”的 cv::detectMultiScale()。

如何执行此提取/转换?

下面的代码示例...

int DetectionProc(void * param){ // async operation
    auto instance =(Detector *)param;
    const unsigned int delay = 1000 / instance->OPS;
    std::vector<dlib::rectangle> detects;
    array2d<rgb_pixel> sample;

    while(instance->OPS){
        unsigned int elapsed = GetTickCount();

        EnterCriticalSection(&instance->cs_buf);
        assign_image(sample,instance->buffer);
        instance->buffer.clear();
        LeaveCriticalSection(&instance->cs_buf);

        if (sample.size()){
            detects = instance->face_detector(sample);
            if (!detects.empty()){
                detection res(GetTickCount());
                if (!instance->smile_detector.empty()){
                    // TODO
                    // extract subimage from detects.front() on sample to cv::Mat face;
                    // instance->smile_detector.detectMultiScale(); on face
                    // set res.smiled to true on success
                }
                EnterCriticalSection(&instance->cs_result);
                instance->result = res;
                LeaveCriticalSection(&instance->cs_result);
            }
        }
        elapsed = GetTickCount() - elapsed;
        Sleep((elapsed < delay) ? (delay - elapsed) : 0);
    }
    return 0;
}

标签: c++opencvdlib

解决方案


有两种方法可以实现这一点,或者通过extract_image_chipsdlib ( docscv::Mat ) 中的功能,或者通过使用相应的 OpenCV API从包装中提取子图像。您将使用哪一个取决于选择对您的其余处理管道的方便程度。

从您的示例中得出结论,OpenCV 路径似乎是最方便的(但请再次查看设计和 API 选项):

// 1.) Wrap your "sample" dlib-image in cv::Mat
//     dlib::toMat() is available through #include <dlib/opencv.h>
cv::Mat sample_mat = dlib::toMat(sample);

// 2.) Iterate through your detections
for (const auto& rect: detects) 
{
    // 3.) Extract the rectangle sub-image using OpenCV
    cv::Mat rect_sub = sample_mat(
        cv::Rect(rect.left(), rect.top(), rect.width(), rect.height()));

    // 4.) Process the sub-image
}

推荐阅读