在 OpenCV 中使用 imread() 加载图像时如何捕获损坏的 JPEG?
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 图像时, 内容。 我能以某种方式抓住它吗?否则我为什么会得到这些信息? 我必须自己检查二进制文件吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
OpenCV(版本 2.4)不会覆盖 libjpeg 的基本错误处理,使它们“无法捕获”。将以下方法添加到
modules/highgui/src/grfmt_jpeg.cpp
中,位于error_exit()
定义的正下方:现在将该方法应用于解码器错误处理程序
:编码器错误处理程序的方法:
像往常一样重新编译并安装 OpenCV。从现在开始,您应该能够像捕获任何其他 OpenCV 错误一样捕获 libjpeg 错误。示例:(
我已经针对上述内容提交了拉取请求,但它被拒绝了,因为它会导致人们在没有异常捕获的情况下阅读图像时出现问题。)
希望这可以帮助任何仍在解决此问题的人。祝你好运。
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 oferror_exit()
:Now apply the method to the decoder error handler:
Apply the method to the encoder error handler as well:
Recompile and install OpenCV as usual. From now on you should be able to catch libjpeg errors like any other OpenCV error. Example:
(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.
修复文件中的错误可能比尝试修复 OpenCV 的加载功能更容易。如果您使用的是 Linux,则可以使用 ImageMagick 来修复一组图像(通常默认安装它):
$ mogrify -set comment 'Image rewriting with ImageMagick' *.jpg
这命令更改文件的属性,保持图像数据不变。但是,图像会被加载并重新保存,从而消除导致损坏错误的额外信息。
如果您需要有关 ImageMagick 的更多信息,可以访问他们的网站: http://www.imagemagick.org/脚本/index.php
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
如果使用
imread()
,则无法捕获它。但是,有一个由imread()
调用的imdecode()
函数。 也许它会给你更多反馈。为此,您必须自行将图像加载到内存中,然后调用解码器。归结为:你必须挖掘 OpenCV 源代码来解决你的问题。
You cannot catch it if you use
imread()
. However there isimdecode()
function that is called byimread()
. Maybe it gives you more feedback. For this you would have to load the image into memory on your own and then call the decoder.It boils down to: You have to dig through the OpenCV sources to solve your problem.
我最近不得不处理这个问题,并在这里找到了解决方案
http:// artax.karlin.mff.cuni.cz/~isa_j1am/other/opencv/
我只需要进行 2 次编辑@ $cv\modules\highgui\src\grfmt_jpeg.cpp。
i had to deal with this recently and found a solution over here
http://artax.karlin.mff.cuni.cz/~isa_j1am/other/opencv/
i just need to make 2 edits @ $cv\modules\highgui\src\grfmt_jpeg.cpp.
我正在使用 opencv python 包读取一些图像,也遇到了这个错误消息。 Python 无法捕获此错误。但是如果你想找到哪个图像被损坏而不按照@Robbert的建议重新编译opencv,你可以尝试以下方法。
首先,您可以查明损坏图像所在的目录,这相当容易。然后进入该目录,使用 提供的
mogrify
命令行工具ImageMagick 更改图像元信息,如 @goe 的建议。上面的命令会将原始 jpg 图像转换为 png 格式,并清理原始图像以删除元信息中的错误。当您运行
mogrify
命令时,它还会输出一些有关目录中哪个图像损坏的消息,以便您可以准确地找到损坏的图像。之后,您可以对原始损坏的 jpg 图像执行任何操作。
I am using opencv python package to read some image and also met this error message. This error can not be catch by Python. But if you want to find which image is corrupted without recompiling opencv as @Robbert suggested, you can try the following method.
First, you can pinpoint the directory where the corrupt images reside, which is fairly easy. Then you go to the directory, and use
mogrify
command line tool provided by ImageMagick to change the image meta info, as suggest by @goe.The above command will convert the original jpg image to png format and also clean the original image to remove errors in meta info. When you run
mogrify
command, it will also output some message about which image is corrupted in the directory so that you can accurately find the corrupted image.After that, you can do whatever you want with the original corrupted jpg image.
任何人偶然发现这篇文章并阅读这个答案。
我必须找到一个损坏的图像文件。
这些网站可以帮助您损坏文件
损坏文件 - 您正在寻找的文件损坏器!
在线损坏文件
第一个和第三个网站没有多大用处。
第二个网站很有趣,因为我可以设置需要损坏的文件量。
我在这里使用的 OpenCV 版本是
3.4.0
我使用正常的
cv2.imread(fileLocation)
fileLocation
损坏图像文件的位置OpenCV 没有显示此处使用的任何损坏文件的任何错误消息
第一和第三网站只提供了一个文件,并且当我尝试打印它们时,两个网站都没有存储它们
第二网站确实让我决定文件的数量需要被破坏
Corruption%
打印图像时的 Opencv 消息4%
None10%
None25%
None50%
无损坏的 JPEG 数据:标记 0x4f 之前有 3 个无关字节
75%
无损坏的 JPEG 数据:标记之前有 153 个无关字节0xb2
100%
损坏的 JPEG 数据:标记 0xc6 之前有 330 个无关字节
无我想我们在这里要做的唯一检查是
如果图像是不是无:
执行您的代码,否则会弹出错误
Any one stumbles upon this post and reads this answer.
I had to get hold of a corrupted image file.
These websites can help you corrupt your file
Corrupt a file - The file corrupter you were looking for!
CORRUPT A FILE ONLINE
First and the third website was not that much useful.
Second website is interesting as I could set the amount of file that I need to corrupt.
OpenCV version I used here is
3.4.0
I used normal
cv2.imread(fileLocation)
fileLocation
Location of corrupted image fileOpenCV didn't show any error message for any of the corrupted files used here
First and Third website only gave one file and both had
None
stored in them, when I tried to print themSecond website did let me decide the amount of file that was needed to be corrupted
Corruption%
Opencv message on printing the image4%
None10%
None25%
None50%
NoneCorrupt JPEG data: 3 extraneous bytes before marker 0x4f
75%
NoneCorrupt JPEG data: 153 extraneous bytes before marker 0xb2
100%
Corrupt JPEG data: 330 extraneous bytes before marker 0xc6
NoneI guess the only check we have to make here would be
if image is not None:
Do your code or else pop an error
您可以将 stderr 重定向到一个文件,然后在 imread 之后,在该文件中搜索字符串“Huffman”。搜索文件后,将其清空。它对我有用,现在我可以丢弃损坏的图像并只处理好的图像。
You can redirect stderr to a file, then after imread, search for the string "Huffman" inside that file. After searching the file, empty it. It works for me and now I am able to discard corrupted images and just process good ones.
如果您使用 imdecode 加载图像,您可以检查 errno :
(在 OpenCV 3.4.1 上测试)
If you load your image with imdecode, you can check errno :
(tested on OpenCV 3.4.1)
我发现问题出在libjpeg上。如果OpenCV使用它,就会出错
您可以尝试 我的解决方案来解决它。它在编译期间禁用 JPEG。之后 OpenCV 无法读/写,但可以工作。
I found that the issue is in libjpeg. If OpenCV uses it, it gets error
You can try my solution to solve it. It disables JPEG during compilation. After that OpenCV cannot read/write, but it works.
我找到了一个简单的解决方案,无需重新编译 openCV。
您可以使用 imagemagick 检测相同的错误,但它会按预期返回错误。请参阅此处的说明:https://stackoverflow.com/a/66283167/2887398
I found an easy solution without the need to recompile openCV.
You can use imagemagick to detect the same errors, however it returns an error as expected. See the description here: https://stackoverflow.com/a/66283167/2887398
我们使用 OpenCV 读取指定文件夹中的每个 JPEG 图像,并通过以质量设置 95 重新保存来覆盖它。此重新编码过程通过标准化图像数据格式来修复任何损坏问题。
经过长时间的调试,这个解决方案解决了我的问题。
We read each JPEG image in the specified folder using OpenCV and overwrite it by re-saving with a quality setting of 95. This re-encoding process fixes any corruption issues by standardizing the image data format.
This solution fixed my problem after a long time of debugging.