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图像时,我是否能够捕捉到这个错误?如果不能,那么我该如何得到这个信息?我是否需要自己检查二进制文件?
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图像时,我是否能够捕捉到这个错误?如果不能,那么我该如何得到这个信息?我是否需要自己检查二进制文件?
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 */
>>> 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
我已经提交了一个拉取请求,但是被拒绝了,因为它会导致人们在没有异常捕获的情况下阅读图像时出现问题。
希望这能帮助仍在苦苦挣扎的任何人解决这个问题。祝好运。
修复文件中的错误可能比试图修复OpenCV的加载函数更容易。如果您正在使用Linux,可以使用ImageMagick对一组图像进行修复(通常已默认安装):
$ mogrify -set comment 'Image rewritten with ImageMagick' *.jpg
此命令更改文件的一个属性,而保留图像数据不变。然而,该图像被加载并重新保存,消除了导致损坏错误的额外信息。
如果需要更多关于ImageMagick的信息,可以访问他们的网站:http://www.imagemagick.org/script/index.php
如果你使用imread()
,就无法捕获它。然而,imread()
调用了imdecode()
函数。也许它会给你更多的反馈。为此,你需要自己将图像加载到内存中,然后调用解码器。
归根结底,你必须深入研究OpenCV源代码来解决你的问题。
--- 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);
}
}
3.4.0
。cv2.imread(fileLocation)
。
fileLocation
是已损坏图像文件的位置。None
。mogrify
命令行工具更改图像元信息,正如@goe所建议的那样。mogrify -set comment "errors fixed in meta info" -format png *.jpg
mogrify
命令时,它还会输出有关目录中哪个图像损坏的一些消息,以便您可以准确地找到损坏的图像。您可以将stderr重定向到文件中,然后在imread之后,在该文件中搜索字符串“Huffman”。搜索完毕后,请清空该文件。这对我很有效,现在我能够丢弃损坏的图像并处理好的图像。
我发现问题出在libjpeg上。如果OpenCV使用它,就会出错。
损坏的JPEG数据:标记0xd9之前有22个多余字节
你可以尝试我的解决方案来解决它。它在编译期间禁用了JPEG。之后OpenCV无法读写JPEG,但它仍然可以工作。
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 ..
我找到了一个简单的解决方案,无需重新编译openCV。您可以使用imagemagick来检测相同的错误,但是它会像预期的那样返回一个错误。请参见此处的说明:https://dev59.com/hYrda4cB1Zd3GeqPRtnx#66283167
std::vector<char> datas();
//Load yout image in datas here
errno = 0;
cv::Mat mat = cv::imdecode(datas, -1);
if (errno != 0)
{
//Error
}
(在 OpenCV 3.4.1 上测试过)