Как я могу поймать поврежденные JPEG при загрузке изображения с imread () в OpenCV?
OpenCV говорит что-то вроде
Corrupt JPEG data: premature end of data segment
или
Corrupt JPEG data: bad Huffman code
или
Corrupt JPEG data: 22 extraneous bytes before marker 0xd9
при загрузке поврежденного изображения jpeg с помощью imread (). Могу я как-нибудь это уловить? Иначе зачем бы мне получать эту информацию? Должен ли я проверить двоичный файл самостоятельно?
8 ответов
вы не можете поймать его, если вы используете imread()
. Однако есть imdecode()
функция, которая вызывается imread()
. может быть это дает вам больше обратной связи. Для этого вам нужно будет загрузить изображение в память самостоятельно, а затем вызвать декодер.
это сводится к: вы должны копаться в источниках OpenCV, чтобы решить вашу проблему.
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, как обычно. Отныне вы должны быть в состоянии поймать ошибки libjpeg, как и любой другой OpenCV ошибка. Пример:
>>> 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
(Я подан запрос на вытягивание для вышеизложенного, но он был отклонен, потому что это вызовет проблемы с людьми, читающими изображения без исключения.)
надеюсь, это поможет любому, кто все еще борется с этой проблемой. Удача.
мне пришлось иметь дело с этим недавно и нашел решение здесь
http://artax.karlin.mff.cuni.cz / ~isa_j1am / другое / opencv/
Мне просто нужно сделать 2 правки @ $cv\modules\highgui\src\grfmt_jpeg.СРР.
--- 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);
}
}
может быть проще исправить ошибку в файле вместо того, чтобы пытаться восстановить функцию загрузки OpenCV. Если вы используете Linux, вы можете использовать ImageMagick для восстановления набора изображений (обычно он устанавливается по умолчанию):
$ mogrify -set comment 'Image rewritten with ImageMagick' *.jpg
эта команда изменяет свойство файла, оставляя данные изображения нетронутыми. Однако изображение загружается и повторно сохраняется, устраняя дополнительную информацию, которая вызывает ошибку повреждения.
Если вам нужна дополнительная информация о ImageMagick вы можете посетить их веб-сайт:http://www.imagemagick.org/script/index.php
вы можете перенаправить stderr в файл, затем после imread найдите строку "Huffman" внутри этого файла. После поиска файла очистите его. Это работает для меня и теперь я могу отбросить испорченные снимки и просто хороших.
Я использую пакет OpenCV python для чтения некоторого изображения, а также встретил это сообщение об ошибке. Эта ошибка не может быть поймана Python. Но если вы хотите найти, какое изображение повреждено без перекомпиляции opencv, как предложил @Robbert, вы можете попробовать следующий метод.
во-первых, вы можете определить каталог, где находятся поврежденные изображения, что довольно легко. Затем перейдите в каталог и используйте mogrify
инструмент командной строки, предусмотренные ImageMagick изменить метаинформация изображения, как предлагает @goe.
mogrify -set comment "errors fixed in meta info" -format png *.jpg
вышеуказанная команда преобразует исходное изображение jpg в формат png, а также очистит исходное изображение, чтобы удалить ошибки в meta info. При запуске mogrify
команда, она также выведет сообщение о том, какое изображение повреждено в каталоге, чтобы вы могли точно найти поврежденное изображение.
после этого вы можете делать все что угодно с исходным поврежденным изображения.
Я обнаружил, что проблема находится в libjpeg. Если OpenCV использует его, он получает ошибку
поврежденные данные JPEG: 22 посторонних байта перед маркером 0xd9
вы можете попробовать мое решение чтобы решить это. Он отключает 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 ..
любой натыкается на этот пост и прочитает этот ответ.
я должен был получить поврежденный файл изображения.
эти веб-сайты могут помочь вам повредить файл
первый и третий сайт был не так уж и полезен.
второй веб-сайт интересен, поскольку я мог бы установить объем файла, который мне нужно повредить.
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:
Сделайте свой код или еще поп ошибка