如何正确保存DLIB对象检测芯片?

时间:2017-04-16 23:01:21

标签: c++ dlib

我无法保存DLIB面部检测模型生成的图像芯片。以下代码详述了我的工作流程。我试图将整个图像保存在下面d_image,这样就可以了。但是,当我尝试保存每个芯片时,我得到了失真的输出(见下面的例子)。我在Ubuntu 16.04上使用dlib 19.4。

// object to store raw image data
cv::Mat rawImage;

// initialize the detector
dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();

// using shape predictor object to create dull_object_detections
dlib::shape_predictor sp;
dlib::deserialize(argv[1]) >> sp;

// for writing out images 
int image_id = 1;

while (true){

    // retrieve image size
    sockt.getData(&image_size, 4, NULL);

    if (image_size > 0) {

        rawImage.create(1, image_size, CV_8UC1);

        // load incoming data from a stream 
        sockt.getData(rawImage.data, image_size, MSG_WAITALL);

        // reshape and correct orientation 
        dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);

        // find the daces!
        std::vector<dlib::rectangle> detections = detector(d_image);

        if (detections.size() > 0){

            // generate additional detection data so we can use 
            // dlib's extract_image_chips function
            std::vector<dlib::full_object_detection> shapes;
            for (int idx = 0; idx < detections.size(); idx++){
                dlib::full_object_detection shape = sp(d_image, detections[idx]);
                shapes.push_back(shape);
            }

            // write each chip to disk
            dlib::array<dlib::array2d<dlib::bgr_pixel>> face_chips;
            dlib::extract_image_chips(d_image, dlib::get_face_chip_details(shapes), face_chips);
            for (int idx = 0; idx < face_chips.size(); idx++){
                std::string fname = argv[2] + std::to_string(image_id) + ".jpg";
                dlib::save_jpeg(face_chips[idx], fname);
                image_id++;
            }

        }

示例保存芯片:

enter image description here

修改:为utils::process_frame添加了评论。此函数接受1xN阵列,并使用OpenCV

解码为JPEG

1 个答案:

答案 0 :(得分:1)

您使用的图片格式出现了问题:

这是OpenCV的灰度(1通道)图像

rawImage.create(1, image_size, CV_8UC1);

这是BGR(3通道)图像 dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);

如果图像的通道数不正确,Dlib应该抛出异常,但它不会在你的情况下抛出它。这意味着在utils::process_frame(rawImage)中某处将图像格式首先更改为3通道检查图像格式

此构造代码rawImage.create(1, image_size, CV_8UC1);构造了1行和image_size cols图像。 图像大小和格式不正确

请注意,dlib不会将图像数据复制到dlib::cv_image<dlib::bgr_pixel> d_image,并且rawImage应该保持不变,其他线程会一直处理

无论如何,您可以致电dlib::toMat,获取OpenCV Mat并使用OpenCV函数保存

<强>更新 还有一件事:

dlib::cv_image<dlib::bgr_pixel> d_image = utils::process_frame(rawImage);

看起来像utils :: process_frame返回一些在构造d_image后被销毁的临时对象。 d_image不保存返回的数据,可能会丢失 所以我建议你改变你的代码:

cv::Mat uncompressed;
tils::process_frame(rawImage, uncompressed);
dlib::cv_image<dlib::bgr_pixel> d_image(uncompressed);;

其中process_frame应该引用cv :: Mat并将其输出保存到其中