2017-04-16 6 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 채널) 이미지를

rawImage.create(1, image_size, CV_8UC1);

이를

는 OpenCV의의 그레이 스케일입니다 :이 함수는 1xN 배열을 받아 OpenCV의에게 이미지 포맷을 사용하는 문제

답변

1

뭔가를 사용하여 JPEG로 디코딩 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::cv_image<dlib::bgr_pixel> d_image에 이미지 데이터를 복사하지 않습니다 dlib과 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는 이력서 참조 : 매트를 가지고 그것으로 출력을 저장해야

+0

감사 : 그래서 당신이 이런 식으로 코드를 변경하는 것이 좋습니다 d_image는 반환 된 데이터를 보유하지 않으며, 그것은 손실 될 수 있습니다 귀하의 의견을하지만 그건 문제가되지 않습니다. 'process_frame' 함수는 OpenCV 함수를 사용하여 1xN 배열을 JPEG로 디코딩합니다. 성공적으로'd_image'를 JPEG로 저장할 수 있습니다. 나는 또한':: toMat'을 사용하여 변환을 시도했지만 저장 될 때 여전히 동일한 결과를 얻는다. – Andrew

+0

@ 앤드류, 이제 진짜 문제를 본 것처럼 보입니다. 트릭을 한 내 대답 – Evgeniy

+0

을 업데이트했습니다! 나는'dlib :: cv_image'를 읽은 후에 데이터를 복사하지 않는다. – Andrew