2012-02-03 1366 views
10

OpenCV的说像如何在OpenCV中使用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图像时

()。 我能以某种方式捕捉到吗?为什么我会得到这些信息呢? 我必须自己检查二进制文件吗?

+0

嗨你有解决这个问题的方法,我也反对OpenCV的这个问题。谢谢! – 2015-12-27 15:02:32

+0

用户也可能有兴趣阅读[post here](https://stackoverflow.com/questions/24805500/can-i-fix-photos-with-corrupt-jpeg-data) – jdhao 2017-11-14 15:03:28

回答

1

如果您使用imread(),则无法捕捉它。但是有imdecode()函数被imread()调用。 也许它给你更多的反馈。为此,您必须自行将图像加载到内存中,然后调用解码器。

归结为:你必须挖掘OpenCV源代码来解决你的问题。

+1

是的..我很害怕有人会告诉我这个;) – Ben 2012-02-03 17:33:26

+0

你有没有找到办法做到这一点,我会很感兴趣,因为我面临同样的问题。 – joon 2012-03-21 23:01:08

+1

imdecode()不提供任何关于libjpeg警告的反馈 – Aubin 2014-12-04 18:35:56

1

我不得不最近处理这个,发现一个解决方案在这里

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

我只是需要做2名编辑@ $ CV \模块\ 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(版本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为以上,但它得到了拒绝,因为它会引起人的读取图像无异常捕获的问题。)

希望这有助于人还是这个问题挣扎。祝你好运。

0

您可以将stderr重定向到一个文件,然后在imread之后,搜索该文件中的字符串“Huffman”。搜索文件后,清空它。它适用于我,现在我能够放弃损坏的图像,并处理好的图像。

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 .. 
+0

您应该在此处发布您的解决方案,而不是将用户指向其他地方。链接用于提供更多信息。 – jdhao 2017-11-14 14:14:59

1

修复文件中的错误可能更容易,而不是尝试修复OpenCV的加载函数。如果你使用Linux,你可以使用ImageMagick的做出赔偿,以一组图片(就是通常要把它默认安装):

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

该命令改变文件的属性而使图像数据不变。但是,图像会被加载并重新保存,从而消除导致损坏错误的额外信息。

如果您需要了解ImageMagick的,你可以访问他们的网站了解更多信息:http://www.imagemagick.org/script/index.php

+0

虽然很难发现错误,但至少我们可以通过这种方式消除错误信息。这是很好的解决方案〜 – jdhao 2017-11-14 14:16:40

0

我使用OpenCV的Python包,阅读一些形象,也遇到了这样的错误消息。这个错误不能被Python捕获。但是如果你想找到哪个图像被破坏,而没有像@Robbert建议的那样重新编译opencv,你可以尝试下面的方法。

首先,您可以精确定位损坏图像所在的目录,这很容易。然后,您转到该目录,并使用ImageMagick提供的mogrify命令行工具更改图像元信息,如@goe所示。

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

上面的命令将原来的JPG图像转换为PNG格式,还清理原始图像的元信息删除错误。当您运行mogrify命令时,它还会输出有关目录中的哪个图像已损坏的消息,以便您可以准确地找到损坏的图像。

之后,你可以做任何你想要的原始损坏的jpg图像。