OpenCV says something like
Corrupt JPEG data: premature end of data segment
or
Corrupt JPEG data: bad Huffman code
or
Corrupt JPEG data: 22 extraneous bytes before marker 0xd9
when loading a corrupt jpeg image with imread(). Can I somehow catch that? Why would I get this information otherwise? Do I have to check the binary file on my own?
The only way to check if file is corrupted is to try reading it as it is described in file format, ie. load BMP as BMP with reading BMP header, BMP data etc. There are many web pages that describe graphics file formats.
Image files can corrupt due to system or user errors. You know your image is corrupt when you are unable to view the image or your image-editing software is producing error messages. You may even see a distorted version of the picture. You can perform a few steps to troubleshoot a corrupt image file.
OpenCV (version 2.4) does not overwrite the basic error handling for libjpeg, making them 'uncatchable'. Add the following method to modules/highgui/src/grfmt_jpeg.cpp
, right below the definition of 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); }
Now apply the method to the decoder error handler:
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 */
Apply the method to the encoder error handler as well:
cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = error_exit; jerr.pub.output_message = output_message; /* Add this line */
Recompile and install OpenCV as usual. From now on you should be able to catch libjpeg errors like any other OpenCV error. Example:
>>> 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
(I've submitted a pull request for the above but it got rejected because it would cause issues with people reading images without exception catching.)
Hope this helps anyone still struggling with this issue. Good luck.
It could be easier to fix the error in the file instead of trying to repair the loading function of OpenCV. If you are using Linux you can use ImageMagick to make reparation to a set of images (is usual to have it installed by default):
$ mogrify -set comment 'Image rewritten with ImageMagick' *.jpg
This command changes a property of the file leaving the image data untouched. However, the image is loaded and resaved, eliminating the extra information that causes the corruption error.
If you need more information about ImageMagick you can visit their website: http://www.imagemagick.org/script/index.php
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With