2012-02-03 10 views
10

OpenCV mówi cośJak mogę przechwytywać uszkodzone pliki JPEG podczas ładowania obrazu za pomocą funkcji imread() w OpenCV?

Corrupt JPEG data: premature end of data segment 

lub

Corrupt JPEG data: bad Huffman code 

lub

Corrupt JPEG data: 22 extraneous bytes before marker 0xd9 

podczas ładowania uszkodzony JPEG z imread(). Czy mogę jakoś to złapać? Dlaczego miałbym uzyskać te informacje w inny sposób? Czy muszę sam sprawdzać plik binarny?

+0

Witam, mam rozwiązanie tego problemu, ja też mam ten problem z OpenCV. Dziękuję Ci! –

+0

użytkowników może być także zainteresowany przeczytaniem [post tutaj] (https://stackoverflow.com/questions/24805500/can-i-fix-photos-with-corrupt-jpeg-data) – jdhao

Odpowiedz

1

Nie możesz tego złapać, jeśli używasz imread(). Istnieje jednak funkcja imdecode(), która jest wywoływana przez imread(). Może daje więcej informacji zwrotnych. W tym celu należałoby wczytać obraz do pamięci, a następnie wywołać dekoder.

Sprowadza się do: Musisz przekopać się przez źródła OpenCV, aby rozwiązać problem.

+1

tak .. Bałem się kogoś powie mi to;) – Ben

+0

Czy kiedykolwiek znalazłeś sposób, aby to zrobić, byłbym bardzo zainteresowany, ponieważ mam do czynienia z tym samym problemem. – joon

+1

imdecode() nie udziela żadnych opinii na temat ostrzeżeń libjpeg – Aubin

1

miałem do czynienia z tym ostatnim i znalazł rozwiązanie tutaj

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

po prostu trzeba zrobić 2 edycje @ $ cv \ modules \ 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 (wersja 2.4) nie zastępuje podstawowej obsługi błędów dla libjpeg, co powoduje, że są one "nierozłączne". Dodaj następującą metodę do modules/highgui/src/grfmt_jpeg.cpp, tuż poniżej definicji 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); 
} 

Teraz zastosowania metody do obsługi błędów dekodera:

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 */ 

zastosować metodę do obsługi błędów enkodera, a także:

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

Ponownie skompiluj i zainstaluj OpenCV jak zwykle. Od tej pory powinieneś być w stanie złapać błędy libjpeg jak każdy inny błąd OpenCV. Przykład:

>>> 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 

(mam submitted a pull request do powyższego, ale został odrzucony, ponieważ spowodowałoby to problemy z osobami czytania obrazów bez wyjątku wzrok.)

Nadzieja to pomaga ktoś nadal zmaga się z tym problemem. Powodzenia.

0

Możesz przekierować stderr do pliku, a następnie po imread, wyszukaj w tym pliku ciąg "Huffman". Po przeszukaniu pliku, opróżnij go. To działa dla mnie i teraz jestem w stanie odrzucić uszkodzone obrazy i po prostu przetwarzać dobre.

0

Znalazłem, że problem jest w libjpeg.Jeśli OpenCV go używa, to dostaje error

danych Corrupt JPEG: 22 bajtów przed obce markera 0xd9

Można spróbować my solution go rozwiązać. Wyłącza JPEG podczas kompilacji. Po tym OpenCV nie może czytać/pisać, ale działa.

+0

Powinieneś zamieścić tutaj swoje rozwiązanie, nie kierując użytkownika do innego miejsca. Linki służą do przekazywania dalszych informacji. – jdhao

1

Naprawienie błędu w pliku może być łatwiejsze niż próba naprawy funkcji ładowania OpenCV. Jeśli używasz systemu Linux można użyć ImageMagick zadośćuczynienia do zestawu obrazów (zwykle się go zainstalowanego domyślnie):

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

Ta komenda zmienia właściwości pliku, pozostawiając dane obrazu nietknięty . Jednak obraz jest ładowany i ponownie zapisywany, eliminując dodatkowe informacje, które powodują błąd korupcji.

Jeżeli potrzebują Państwo więcej informacji o ImageMagick można odwiedzić ich stronę internetową: http://www.imagemagick.org/script/index.php

+0

Chociaż trudno jest złapać błąd, przynajmniej możemy wyeliminować komunikat o błędzie w ten sposób. To dobre rozwiązanie ~ – jdhao

0

Używam OpenCV pakiet python czytać jakiś obraz, a także spotkał się ten komunikat o błędzie. Ten błąd nie może zostać przechwycony przez Python. Ale jeśli chcesz dowiedzieć się, który obraz jest uszkodzony, nie rekompilując opencv jak sugerował @Robbert, możesz wypróbować następującą metodę.

Po pierwsze, możesz wskazać katalog, w którym znajdują się uszkodzone obrazy, co jest dość łatwe. Następnie przejdź do katalogu i użyj narzędzia wiersza polecenia mogrify dostarczonego przez ImageMagick, aby zmienić meta info obrazu, jak sugeruje @goe.

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

Powyższe polecenie konwersji oryginalnego obrazu JPG do PNG i również wyczyścić oryginalnego obrazu w celu usunięcia błędów w meta informacji. Po uruchomieniu polecenia mogrify wyświetli również komunikat o tym, który obraz jest uszkodzony w katalogu, aby można było dokładnie znaleźć uszkodzony obraz.

Po tym możesz zrobić, co chcesz z oryginalnym uszkodzonym obrazem jpg.

Powiązane problemy