【问题标题】:Conversion from OpenCV to PIL is not accurate从 OpenCV 到 PIL 的转换不准确
【发布时间】:2018-12-07 15:17:58
【问题描述】:

当我将图像从 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]

我认为索引可能会关闭一个,但事实并非如此。有没有办法来解决这个问题? 这是图片(但其他人也一样):

【问题讨论】:

    标签: python opencv python-imaging-library


    【解决方案1】:

    这表明 PIL 和 OpenCV 正在使用不同版本的 libjpeg 或使用不同的参数。如果您不要求它不要这样做,OpenCV 似乎会尝试使用 libjpeg-turbo,请参阅此处的代码:https://github.com/opencv/opencv/blob/master/cmake/OpenCVFindLibsGrfmt.cmake#L39

    【讨论】:

      【解决方案2】:

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

      例如,当我尝试使用旧版本的 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 会查找随操作系统映像提供的编解码器。安装相关软件包(不要忘记开发文件,例如 Debian* 和 Ubuntu* 中的“libjpeg-dev”)以获得编解码器支持或在 CMake 中打开 OPENCV_BUILD_3RDPARTY_LIBS 标志。

      所以在 Debian/Ubuntu 系统上,opencv 可能会使用操作系统自带的libjpeg-turbo。 (具体来说,我的机器安装了版本 8。)

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

      你可以试试这个:

      • 如果您有相对较新的 PIL/Pillow,请将其降级到版本

         pip install Pillow==3.4.2
        
      • 如果您有旧 Pillow 版本,您可以尝试将其升级到版本 >= 4.0.0

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

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

      【讨论】:

        【解决方案3】:

        libjpeg 版本可能不同

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

        ffmpeg -i 1.jpg 1.bmp

        比opencv输出和PIL输出会一样

        【讨论】:

          【解决方案4】:

          由于 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

          【讨论】:

          • 这不是被问到的。问题是为什么 OpenCV 将一个像素解码为 [108 118 112] 而 PIL/Pillow 将相同的像素解码为 s [104 118 112]。这不是颜色顺序的问题。
          猜你喜欢
          • 2012-12-17
          • 2020-05-24
          • 1970-01-01
          • 2014-05-21
          • 2012-08-25
          • 1970-01-01
          • 2020-06-19
          • 1970-01-01
          • 2012-11-14
          相关资源
          最近更新 更多