2012-02-03 176 views
10

OpenCV的說像如何在OpenCV中使用imread()加載圖像時捕獲損壞的JPEG?

Corrupt JPEG data: premature end of data segment 

Corrupt JPEG data: bad Huffman code 

Corrupt JPEG data: 22 extraneous bytes before marker 0xd9 
加載與imread損壞的JPEG圖像時

()。 我能以某種方式捕捉到嗎?爲什麼我會得到這些信息呢? 我必須自己檢查二進制文件嗎?

+0

嗨你有解決這個問題的方法,我也反對OpenCV的這個問題。謝謝! – 2015-12-27 15:02:32

+0

用戶也可能有興趣閱讀[post here](https://stackoverflow.com/questions/24805500/can-i-fix-photos-with-corrupt-jpeg-data) – jdhao 2017-11-14 15:03:28

回答

1

如果您使用imread(),則無法捕捉它。但是有imdecode()函數被imread()調用。 也許它給你更多的反饋。爲此,您必須自行將圖像加載到內存中,然後調用解碼器。

歸結爲:你必須挖掘OpenCV源代碼來解決你的問題。

+1

是的..我很害怕有人會告訴我這個;) – Ben 2012-02-03 17:33:26

+0

你有沒有找到辦法做到這一點,我會很感興趣,因爲我面臨同樣的問題。 – joon 2012-03-21 23:01:08

+1

imdecode()不提供任何關於libjpeg警告的反饋 – Aubin 2014-12-04 18:35:56

1

我不得不最近處理這個,發現一個解決方案在這裏

http://artax.karlin.mff.cuni.cz/~isa_j1am/other/opencv/

我只是需要做2名編輯@ $ CV \模塊\ highgui的\ src \ grfmt_jpeg.cpp。

--- opencv-1.0.0.orig/otherlibs/highgui/grfmt_jpeg.cpp 2006-10-16 13:02:49.000000000 +0200 
+++ opencv-1.0.0/otherlibs/highgui/grfmt_jpeg.cpp 2007-08-11 09:10:28.000000000 +0200 
@@ -181,7 +181,7 @@ 
      m_height = cinfo->image_height; 
      m_iscolor = cinfo->num_components > 1; 

-   result = true; 
+   result = (cinfo->err->num_warnings == 0); 
     } 
    } 

@@ -405,8 +405,9 @@ 
         icvCvt_CMYK2Gray_8u_C4C1R(buffer[0], 0, data, 0, cvSize(m_width,1)); 
       } 
      } 
-   result = true; 
+ 
      jpeg_finish_decompress(cinfo); 
+   result = (cinfo->err->num_warnings == 0); 
     } 
    } 
4

OpenCV(版本2.4)不會覆蓋libjpeg的基本錯誤處理,使它們'不可捕捉'。下面的方法添加到modules/highgui/src/grfmt_jpeg.cpp,右下方的error_exit()定義:

METHODDEF(void) 
output_message(j_common_ptr cinfo) 
{ 
    char buffer[JMSG_LENGTH_MAX]; 

    /* Create the message */ 
    (*cinfo->err->format_message) (cinfo, buffer); 

    /* Default OpenCV error handling instead of print */ 
    CV_Error(CV_StsError, buffer); 
} 

現在應用的方法給解碼器錯誤處理程序:

state->cinfo.err = jpeg_std_error(&state->jerr.pub); 
state->jerr.pub.error_exit = error_exit; 
state->jerr.pub.output_message = output_message; /* Add this line */ 

應用方法將編碼錯誤處理程序,以及:

cinfo.err = jpeg_std_error(&jerr.pub); 
jerr.pub.error_exit = error_exit; 
jerr.pub.output_message = output_message; /* Add this line */ 

像往常一樣重新編譯和安裝OpenCV。從現在開始,你應該能夠像其他任何OpenCV錯誤一樣捕獲libjpeg錯誤。例如:

>>> cv2.imread("/var/opencv/bad_image.jpg") 
OpenCV Error: Unspecified error (Corrupt JPEG data: 1137 extraneous bytes before marker 0xc4) in output_message, file /var/opencv/opencv-2.4.9/modules/highgui/src/grfmt_jpeg.cpp, line 180 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
cv2.error: /var/opencv/opencv-2.4.9/modules/highgui/src/grfmt_jpeg.cpp:180: error: (-2) Corrupt JPEG data: 1137 extraneous bytes before marker 0xc4 in function output_message 

(我submitted a pull request爲以上,但它得到了拒絕,因爲它會引起人的讀取圖像無異常捕獲的問題。)

希望這有助於人還是這個問題掙扎。祝你好運。

0

您可以將stderr重定向到一個文件,然後在imread之後,搜索該文件中的字符串「Huffman」。搜索文件後,清空它。它適用於我,現在我能夠放棄損壞的圖像,並處理好的圖像。

0

我發現問題出在libjpeg中。如果OpenCV的使用它,它就會錯誤

腐敗JPEG數據:標記0xd9

前22個字節無關,您可以嘗試my solution來解決它。它在編譯期間禁用JPEG。之後,OpenCV無法讀取/寫入,但它的作品。

cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_SHARED_LIBS=OFF -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D WITH_JPEG=OFF -D WITH_IPP=OFF .. 
+0

您應該在此處發佈您的解決方案,而不是將用戶指向其他地方。鏈接用於提供更多信息。 – jdhao 2017-11-14 14:14:59

1

修復文件中的錯誤可能更容易,而不是嘗試修復OpenCV的加載函數。如果你使用Linux,你可以使用ImageMagick的做出賠償,以一組圖片(就是通常要把它默認安裝):

$ mogrify -set comment 'Image rewritten with ImageMagick' *.jpg

該命令改變文件的屬性而使圖像數據不變。但是,圖像會被加載並重新保存,從而消除導致損壞錯誤的額外信息。

如果您需要了解ImageMagick的,你可以訪問他們的網站了解更多信息:http://www.imagemagick.org/script/index.php

+0

雖然很難發現錯誤,但至少我們可以通過這種方式消除錯誤信息。這是很好的解決方案〜 – jdhao 2017-11-14 14:16:40

0

我使用OpenCV的Python包,閱讀一些形象,也遇到了這樣的錯誤消息。這個錯誤不能被Python捕獲。但是如果你想找到哪個圖像被破壞,而沒有像@Robbert建議的那樣重新編譯opencv,你可以嘗試下面的方法。

首先,您可以精確定位損壞圖像所在的目錄,這很容易。然後,您轉到該目錄,並使用ImageMagick提供的mogrify命令行工具更改圖像元信息,如@goe所示。

mogrify -set comment "errors fixed in meta info" -format png *.jpg 

上面的命令將原來的JPG圖像轉換爲PNG格式,還清理原始圖像的元信息刪除錯誤。當您運行mogrify命令時,它還會輸出有關目錄中的哪個圖像已損壞的消息,以便您可以準確地找到損壞的圖像。

之後,你可以做任何你想要的原始損壞的jpg圖像。