Преобразование из OpenCV в PIL не является точным - PullRequest
0 голосов
/ 28 июня 2018

Когда я конвертирую изображение из PIL в OpenCV, цвета меняются незначительно.

from PIL import Image
import cv2
import numpy as np
image = cv2.imread('1.jpg')
image1=Image.open('1.jpg')
image1 = cv2.cvtColor(np.array(image1), cv2.COLOR_RGB2BGR)
print(image[79])
print(image1[79])

Первые четыре строки:

[144 151 148]
[101 108 105]
[121 128 125]
[108 118 112]

и

[140 152 146]
[ 97 109 103]
[117 129 123]
[104 118 112]

Я думал, что индексирование может быть отключено одним, но это не так. Есть ли способ это исправить? Это изображение (но на других тоже):

image

Ответы [ 4 ]

0 голосов
/ 11 марта 2019

версия libjpeg может отличаться

Преобразование исходного .jpg изображения в .bmp изображение

ffmpeg -i 1.jpg 1.bmp

чем выходные данные opencv и PIL будут одинаковыми

0 голосов
/ 01 июля 2018

Это поведение зависит от различных несовместимых версий libjpeg , используемых cv2 и PIL / Pillow, как уже указывалось @fireant.

Например, когда я пытаюсь запустить этот код с более старыми версиями Pillow (например, 3.4.2), он генерирует тот же вывод. В моих тестах, Pillow 3.4.2 и старше (самая старая версия пробовала 2.2.0) все используют libjpeg 8, в то время как Pillow 4.0.0 и новее используют libjpeg 9.2.

OpenCV, с другой стороны, может использовать разных версий в разных системах :

В ОС Microsoft Windows * и MacOSX * кодеки, поставляемые с образом OpenCV (libjpeg, libpng, libtiff и libjasper), используются по умолчанию.

В Linux *, BSD-версиях и других Unix-подобных операционных системах с открытым исходным кодом OpenCV ищет кодеки, поставляемые с образом ОС. Установите соответствующие пакеты (не забудьте файлы разработки, например, «libjpeg-dev» в Debian * и Ubuntu *), чтобы получить поддержку кодека или включите флаг OPENCV_BUILD_3RDPARTY_LIBS в CMake.

Таким образом, в системах Debian / Ubuntu opencv может использовать libjpeg-turbo, который поставляется с ОС. (В частности, на моей машине была установлена ​​версия 8.)

Способ исправить это - убедиться, что и Pillow, и OpenCV используют одну и ту же версию libjpeg.

Вы можете попробовать это:

  • если у вас относительно новый PIL / Pillow, понизьте его до версии <= 3.4.2 (это то, что у меня сработало) </p>

    pip install Pillow==3.4.2
    
  • если у вас старая версия Pillow, вы можете попробовать обновить ее до версии> = 4.0.0

Если это не поможет, ваше решение может быть одним из двух:

  • перекомпилируйте ваш OpenCV с тем же вкусом libjpeg, который использовал Pillow.
  • переустановка Pillow из исходного кода с использованием той же версии libjpeg, что и в OpenCV.
0 голосов
/ 01 июля 2018

Поскольку OpenCV считывает изображение в формате BGR с помощью cv2.imread (), нам нужно преобразовать его обратно в RGB перед передачей в PIL.

Вот пример чтения изображения с OpenCv и без изменений с сохранением его в PIL:

image = cv2.imread('test.jpg')
pil_img = PIL.Image.fromarray(image)
pil_img.save('pil_img.jpg', 'JPEG')

Изображение 'test.jpg': введите описание изображения здесь

Изображение 'pil_img.jpg': введите описание изображения здесь

Чтобы исправить это, нам нужно использовать cv2.cvtColor, чтобы изменить изображение на RGB

correct_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
pil_img = PIL.Image.fromarray(correct_img)
pil_img.save('pil_correct_img.jpg', 'JPEG')

Результат: введите описание изображения здесь

0 голосов
/ 29 июня 2018

Это говорит о том, что PIL и OpenCV используют разные версии libjpeg или используют его с разными параметрами. Также кажется, что OpenCV пытается использовать libjpeg-turbo, если вы не просите об этом, смотрите код здесь: https://github.com/opencv/opencv/blob/master/cmake/OpenCVFindLibsGrfmt.cmake#L39

...