2017-04-16 61 views
1

我无法保存由DLIB人脸检测模型生成的图像芯片。以下代码详细介绍了我的工作流我试图保存下面的整个图像,d_image,这工作得很好。但是,当我尝试保存每个芯片时,我会得到失真的输出(请参见下面的示例)。我在Ubuntu 16.04上使用dlib 19.4。如何正确保存DLIB物体检测芯片?

// 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。此函数接受的1×N阵列和使用的OpenCV

回答

1

有点毛病图像格式使用的是解码作为JPEG:

这是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_imagerawImage应保持被其它线程保持不变,你可以调用dlib::toMat,得到的OpenCV垫,并用OpenCV函数保存

UPDATE: 一两件事在这里:

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 ::垫,其输出保存到它

+0

谢谢为了您的评论,但这不是问题。函数'process_frame'使用OpenCV函数将1xN数组解码为JPEG格式。我也可以将'd_image'成功保存为JPEG格式。我也尝试使用':: toMat'进行转换,但保存时仍然获得相同的输出。 – Andrew

+0

@Andrew,看起来像现在我看到了真正的问题,我已经更新了我的回答 – Evgeniy

+0

那就是诀窍!我应该在阅读后排队阅读'dlib :: cv_image'不会复制数据。 – Andrew