2017-04-16 2 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にコメントを追加しました。この関数は、1xNの配列を受け取り、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_imageに画像データをコピーしないと処理がとにかく

を終了するまでrawImageが他のスレッドによって変更されないまま必要があり、あなたがdlib::toMatを呼び出すことができ、 OpenCVのマットを取得し、OpenCVの関数で保存

UPDATE: ここにもう一つ:

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

のように見えます。utils :: process_frameは、d_imageの構築後に破棄される一時オブジェクトを返します。

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

process_frameがCVへの参照::マットを取ると、それにその出力を保存する必要があり

+0

ありがとう:だから私は、あなたがこのようなあなたのコードを変更することをお勧めd_imageは、返されたデータを保持していない、それは を失ったことができますあなたのコメントのためにそれは問題ではありません。関数process_frameは、OpenCV関数を使用して1xN配列をJPEGにデコードします。私は 'd_image'をJPEGでも正常に保存できます。 ':: toMat'を使って変換しようとしましたが、保存しても同じ出力が得られます。 – Andrew

+0

@Andrew、現実の問題を見ているように見えますが、私は自分の答えを更新しました – Evgeniy

+0

そのトリックをしました!私は 'dlib :: cv_image'を読んだ後にデータをコピーしないでキューに入れたはずです。 – Andrew

関連する問題