【问题标题】:color space transformation in opencv (RGB -> LAB) - red does not produce expected valuesopencv(RGB -> LAB)中的颜色空间转换 - 红色不会产生预期值
【发布时间】:2020-08-06 15:53:05
【问题描述】:

以下使用 RGB 颜色 255,0,0 创建红色图像

import numpy as np
import matplotlib.pyplot as plt
import cv2

width = 5
height = 2

array = np.zeros([height, width, 3], dtype=np.uint8)
array[:,:] = [255, 0, 0] # make it red

print(array)

plt.imshow(array)
plt.show()

输出:

[[[255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]]

 [[255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]]]

如果我将数组转换为 LAB 空间:

array = cv2.cvtColor(array, cv2.COLOR_BGR2LAB)

print(array)

结果如下所示:

[[[ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]]

 [[ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]]]

根据http://colorizer.org/,红色的值应该是:

lab(53.23, 80.11, 67.22)

为什么 opencv 会产生不同的值?我错过了什么吗?有没有可以查找的网站,例如,opebcv 的 Lab 颜色编号中的红色?谢谢。

PS:

一个问题是我使用了 COLOR_BGR2LAB 而不是 COLOR_RGB2LAB(感谢 Mark Setchell),但它仍然没有产生预期的 53.23、80.11、67.22 向量:54.4 83.2 78。这不接近但不一样。 ..

import numpy as np
import matplotlib.pyplot as plt
import cv2

width = 5
height = 2

array = np.zeros([height, width, 3], dtype=np.uint8)
array[:,:] = [255, 0, 0] # make it red

print(array)

array = cv2.cvtColor(array, cv2.COLOR_RGB2LAB)
array = array / 2.5

print(array)

【问题讨论】:

    标签: python opencv


    【解决方案1】:

    您以 RGB 顺序创建图像,所以这个

    array = cv2.cvtColor(array, cv2.COLOR_BGR2LAB)
    

    应该是:

    array = cv2.cvtColor(array, cv2.COLOR_RGB2LAB)
    

    如果你使用 OpenCV cv2.imshow(array)cv2.waitKey() 显示它,你会看到 OpenCV 认为它是蓝色的。


    关于您看到的在线转换器和 OpenCV 之间的差异,我只能假设这与使用uint8 RGB 值产生的舍入误差有关。如果你转换成float 类型,问题就消失了:

    Lab = cv2.cvtColor(array.astype(np.float32), cv2.COLOR_RGB2LAB)
    
    # Result
    array([[[53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125]],
    
           [[53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125],
            [53.240967, 80.09375 , 67.203125]]], dtype=float32)
    

    顺便说一句,我注意到scikit-image 选择在您传递float 时自动返回给您uint8

    from skimage import color
    import numpy as np
    
    # Make a rather small red image
    array = np.full((1, 1, 3), [255,0,0], dtype=np.uint8)
    
    # Convert to Lab with scikit-image
    Lab = color.rgb2lab(array)
    
    # Result
    array([[[53.24058794, 80.09230823, 67.20275104]]])
    

    只是为了好玩,当我们在做的时候,看看 ImageMagick 是怎么做到的:

    magick xc:red -colorspace lab txt:
    # ImageMagick pixel enumeration: 1,1,65535,cielab
    0,0: (34891.4,53351.7,17270.9)  #884BD068C376 cielab(53.2408,80.0943,67.202)
    

    【讨论】:

    • 谢谢。现在我得到:136 208 195 再次不接近我的预期:53.23、80.11、67.22(根据colorizer.org
    • 它们被缩放到范围 0..255(以适应 8 位无符号字节)而不是 0..100。除以 2.55
    • 我不在电脑前,但您可以尝试使用float 看看您是否靠近array = cv2.cvtColor(array.astype(np.float32), cv2.COLOR_BGR2LAB)
    • 我不是 AT 电脑?
    • 酷 - 抱歉花了这么长时间 - 很高兴我们最终到达那里 ?
    猜你喜欢
    • 2017-01-12
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多