从OpenCV到PIL的转换不准确

时间:2018-06-28 13:48:11

标签: python opencv python-imaging-library

当我将图像从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 :(得分:1)

此行为取决于cv2和PIL / Pillow使用的libjpeg的不同不兼容版本,如@fireant已经指出的那样。

例如,当我尝试使用旧版本的Pillow(例如3.4.2)运行此代码时,它会生成相同的输出。在我的测试中,Pillow 3.4.2及更高版本(尝试的最旧版本是2.2.0)都使用libjpeg 8,而Pillow 4.0.0及更高版本使用libjpeg 9.2。

另一方面,OpenCV可能使用different versions on different systems

  

在Microsoft Windows * OS和MacOSX *上,默认情况下使用OpenCV映像附带的编解码器(libjpeg,libpng,libtiff和libjasper)。

     

在Linux *,BSD风格和其他类似Unix的开源操作系统上,OpenCV寻找OS映像随附的编解码器。安装相关的软件包(不要忘记在Debian *和Ubuntu *中忘记开发文件,例如“ libjpeg-dev”)以获得编码解码器支持或在CMake中打开OPENCV_BUILD_3RDPARTY_LIBS标志。

因此在Debian / Ubuntu系统上,opencv可能使用操作系统随附的libjpeg-turbo。 (特别是我的机器已安装版本8。)

解决此问题的方法是确保Pillow和OpenCV使用相同的libjpeg版本。

您可以尝试以下方法:

  • 如果您具有相对较新的PIL / Pillow,请将其降级为<= 3.4.2(这对我有用)

    pip install Pillow==3.4.2
    
  • 如果您使用的是旧版本的枕头,则可以尝试将其升级到> = 4.0.0

如果这没有帮助,则您的解决方案可以是以下两种之一:

  • 使用与Pillow相同的libjpeg风格重新编译OpenCV。
  • 使用与OpenCV相同的libjpeg版本从源代码重新安装Pillow。

答案 1 :(得分:0)

这表明PIL和OpenCV正在使用不同版本的libjpeg或将其与不同参数一起使用。同样,如果您不要求OpenCV尝试使用libjpeg-turbo,请尝试在此处查看代码:https://github.com/opencv/opencv/blob/master/cmake/OpenCVFindLibsGrfmt.cmake#L39

答案 2 :(得分:0)

libjpeg版本可能不同

将原始.jpg图像转换为.bmp图像

ffmpeg -i 1.jpg 1.bmp

比opencv输出和PIL输出要相同

答案 3 :(得分:-1)

由于OpenCV使用cv2.imread()以BGR格式读取图像,因此我们需要先将其转换回RGB,然后再将其提供给PIL。

这是一个使用OpenCv读取图像并且不进行任何更改而使用PIL保存图像的示例:

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

“ test.jpg”图片: enter image description here

“ pil_img.jpg”图片: enter image description here

要纠正此问题,我们需要使用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')

结果:enter image description here