Как я могу поймать поврежденные JPEG при загрузке изображения с imread () в OpenCV? - PullRequest
17 голосов
/ 03 февраля 2012

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 ().Могу ли я как-то это уловить?Зачем мне получать эту информацию в противном случае?Нужно ли проверять двоичный файл самостоятельно?

Ответы [ 9 ]

7 голосов
/ 07 октября 2014

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

отправил запрос на получение для вышеуказанного, но он был отклонен, потому что это может вызвать проблемы с людьми, читающими изображения без перехвата исключений.)

Надеюсь, это поможет любому, кто все еще борется с этой проблемой.Удачи.

2 голосов
/ 12 июля 2017

Может быть проще исправить ошибку в файле, чем пытаться восстановить функцию загрузки OpenCV. Если вы используете Linux, вы можете использовать ImageMagick для восстановления набора изображений (обычно он устанавливается по умолчанию):

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

Эта команда изменяет свойство файла, оставляя данные изображения без изменений. Тем не менее, изображение загружается и сохраняется, исключая дополнительную информацию, которая вызывает ошибку повреждения.

Если вам нужна дополнительная информация о ImageMagick, посетите их веб-сайт: http://www.imagemagick.org/script/index.php

2 голосов
/ 10 июля 2013

Мне пришлось недавно разобраться с этим и найти решение здесь

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);
         }
     }
2 голосов
/ 03 февраля 2012

Вы не можете поймать его, если используете imread(). Однако есть функция imdecode(), которая вызывается imread(). Может быть, это дает вам больше отзывов. Для этого вам придется самостоятельно загрузить изображение в память, а затем вызвать декодер.

Это сводится к следующему: Вы должны копаться в источниках OpenCV, чтобы решить вашу проблему.

1 голос
/ 14 марта 2018

Кто-нибудь наткнется на этот пост и прочитает этот ответ.

Мне пришлось получить поврежденный файл изображения.

Эти веб-сайты могут помочь вам испортить ваш файл

Первый и третий веб-сайт не былэто очень полезно.

Второй веб-сайт интересен тем, что я могу указать количество файлов, которое мне нужно испортить.

Версия OpenCV, которую я здесь использовал, 3.4.0

Iиспользуется нормально 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: Ваш код или иначе выдать ошибку

1 голос
/ 14 ноября 2017

Я использую пакет opencv python для чтения некоторых изображений, а также встретил это сообщение об ошибке. Эта ошибка не может быть поймана Python. Но если вы хотите найти, какое изображение повреждено, без перекомпиляции opencv, как подсказывает @Robbert, вы можете попробовать следующий метод.

Во-первых, вы можете указать каталог, в котором находятся поврежденные изображения, что довольно просто. Затем вы идете в каталог и используете mogrify инструмент командной строки, предоставленный ImageMagick , чтобы изменить метаинформацию изображения, как подсказывает @ goe.

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

Приведенная выше команда преобразует исходное изображение jpg в формат png, а также очищает исходное изображение для устранения ошибок в метаинформации. Когда вы запускаете команду mogrify, она также выводит сообщение о том, какое изображение повреждено в каталоге, чтобы вы могли точно найти поврежденное изображение.

После этого вы можете делать все, что захотите, с исходным искаженным изображением jpg.

0 голосов
/ 18 декабря 2018

Если вы загружаете ваше изображение с помощью 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)

0 голосов
/ 10 апреля 2016

Я обнаружил, что проблема в 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  ..
0 голосов
/ 26 августа 2015

Вы можете перенаправить stderr в файл, а затем, после imread, найти строку «Хаффман» внутри этого файла.После поиска файла очистите его.Это работает для меня, и теперь я могу отказаться от поврежденных изображений и просто обработать хорошие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...