OpenCV说的是
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 :(得分:6)
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对于上述内容,但它被拒绝了,因为它会导致人们在没有异常捕获的情况下阅读图片时出现问题。)
希望这有助于任何仍在努力解决这个问题的人。祝你好运。
答案 1 :(得分:2)
如果使用imread()
,则无法捕捉到它。但是imdecode()
调用了imread()
函数。 也许它会为您提供更多反馈。为此,您必须自己将图像加载到内存中,然后调用解码器。
归结为:您必须深入了解OpenCV来源以解决您的问题。
答案 2 :(得分:2)
我最近不得不处理这个问题并在这里找到了解决方案
http://artax.karlin.mff.cuni.cz/~isa_j1am/other/opencv/
我只需要进行2次编辑@ $ 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);
}
}
答案 3 :(得分:2)
在文件中修复错误可能更容易,而不是尝试修复OpenCV的加载功能。如果您使用的是Linux,则可以使用ImageMagick对一组图像进行修复(通常默认安装它):
$ mogrify -set comment 'Image rewritten with ImageMagick' *.jpg
此命令更改文件的属性,使图像数据保持不变。但是,图像被加载并重新保存,从而消除了导致损坏错误的额外信息。
如果您需要有关ImageMagick的更多信息,可以访问他们的网站:http://www.imagemagick.org/script/index.php
答案 4 :(得分:1)
我正在使用opencv python包来读取一些图像,并且还遇到了此错误消息。 Python无法捕获此错误。但是如果你想在不重新编译opencv的情况下找到哪个图像被破坏,可以尝试以下方法。
首先,您可以精确定位损坏图像所在的目录,这非常简单。然后转到目录,并使用ImageMagick 提供的mogrify
命令行工具更改图像元信息,如@goe所示。
mogrify -set comment "errors fixed in meta info" -format png *.jpg
上述命令会将原始jpg图像转换为png格式,并清除原始图像以删除元信息中的错误。当您运行mogrify
命令时,它还会输出一些有关目录中哪个图像已损坏的消息,以便您可以准确地找到损坏的图像。
之后,您可以使用原始损坏的jpg图像执行任何操作。
答案 5 :(得分:0)
您可以将stderr重定向到文件,然后在imread之后,在该文件中搜索字符串“Huffman”。搜索文件后,清空它。它适用于我,现在我可以丢弃损坏的图像,只处理好的图像。
答案 6 :(得分: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 ..
答案 7 :(得分:0)
任何人都会在这篇文章中发现并读到这个答案。
我不得不抓住一个损坏的图像文件。
这些网站可以帮助您破坏文件
第一个和第三个网站没那么有用。
第二个网站很有意思,因为我可以设置我需要破坏的文件数量。
我在这里使用的OpenCV版本是3.4.0
我使用普通cv2.imread(fileLocation)
fileLocation
损坏的图片文件的位置
OpenCV没有显示此处使用的任何损坏文件的任何错误消息
当我尝试打印时,第一个和第三个网站只提供了一个文件,并且两个文件都存有None
第二个网站确实让我决定了需要损坏的文件数量
Corruption%
关于打印图像的Opencv消息
4%
无
10%
无
25%
无
50%
无Corrupt JPEG data: 3 extraneous bytes before marker 0x4f
75%
无Corrupt JPEG data: 153 extraneous bytes before marker 0xb2
100%
Corrupt JPEG data: 330 extraneous bytes before marker 0xc6
无
我想我们必须在这里做的唯一检查是
if image is not None:
做你的代码或者弹出错误
答案 8 :(得分:0)
如果使用imdecode加载图像,则可以检查errno:
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上测试)
答案 9 :(得分:0)
我找到了一个简单的解决方案,无需重新编译 openCV。 您可以使用 imagemagick 来检测相同的错误,但它会按预期返回错误。请参阅此处的说明:https://stackoverflow.com/a/66283167/2887398