在Python中基于亮度获取像素的RGB值

2024-04-19 14:46:41 发布

您现在位置:Python中文网/ 问答频道 /正文

试图找出如何完成这项任务:我想根据亮度选择图像的像素,然后获取这些像素的rgb值

我最初的想法是使用OpenCV在图像灰度上绘制直方图:

img = cv2.imread('test.jpg',0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])

但我不确定如何识别直方图中特定区域中的像素在图像中的位置

或者,我发现这个公式可以得到亮度:

(0.2126*R + 0.7152*G + 0.0722*B)

所以我想我可以用这个公式迭代图像中的任何一个像素,并获取与我选择的亮度级别相匹配的像素

有没有更好的方法在Python中实现这一点


Tags: test图像img绘制rgb像素直方图cv2
1条回答
网友
1楼 · 发布于 2024-04-19 14:46:41

首先,虽然sRGB或Rec709的系数是正确的,但要将颜色转换为Y

    (0.2126*R + 0.7152*G + 0.0722*B)

…它们要求RGB通道全部线性化,以消除任何伽马编码

其次,这些是Rec709或sRGB的系数,但其他颜色空间需要不同的系数

图书馆

我推荐KenSolaar的ColorScience,这是一个python库,可以转换为亮度,并使用numpy和矢量化数学

https://github.com/colour-science/colour

转换和跟踪像素值

直接将sRGB像素转换为亮度:

  1. 将sRGB值解析为离散的RʹGʹBʹ值。我们将假设它
  2. 分别除以255.0
  3. 取下TRC(又名伽马)。
    • sRGB和其他几种颜色空间的简单方法是使用^2.2的指数对每个RʹGʹBʹ通道应用功率曲线
  4. 然后对亮度Y应用系数和总和。
    • (0.2126*R+0.7152*G+0.0722*B)

综上所述:

    imgPixel = 0xAACCFF

    R = (imgPixel & 0xFF0000) >> 16
    G = (imgPixel & 0x00FF00) >> 8
    B = (imgPixel & 0x0000FF)

    Y = 0.2126*(R/255.0)**2.2 + 0.7152*(G/255.0)**2.2 + 0.0722*(B/255.0)**2.2 

这是最简单的,但仍然相当准确,但是一些纯粹主义者可能建议使用IEC指定的sRGB TRC,这在分段和计算上更昂贵:

# Piecewise sRGB TRC to Linear (only red is shown in this example)

    if R <= 0.04045:
       R / 12.92
    else: 
    (( R + 0.055) / 1.055) ** 2.4

不是吗?

下一个问题是,如何确定像素,这只是创建并填充一个列表(数组),其中包含与亮度匹配的像素的坐标和颜色值

是否要将亮度量化回8位整数值?还是停留在0.0到1.0之间并定义一个范围?后者通常最有用,所以让我们这样做吧

对于cv2.imread('test.jpg',1)不要将标志设置为0-您将创建自己的灰度,并希望保存颜色像素值,对吗

因此,使用前面的示例,但使用三值分段TRC方法,并添加一个循环,为找到的像素添加一个数组:

          # declare some variables
    Llo = 0.18  # Lo luminance range
    Lhi = 0.20  # Hi range choosing pixels between here and Lo
    results = [[]]
    imgPixel = 0x000000
    
    img = cv2.imread('test.jpg',1) # set flag to 1 (or omit) for color — you're going to make your own greyscale.

    rows,cols = img.shape

    for ir in range(rows):
      for ic in range(cols):
         imgPixel = img[ir,ic]
         
         R = ((imgPixel & 0xFF0000) >> 16) / 255.0
         G = ((imgPixel & 0x00FF00) >> 8 ) / 255.0
         B = ((imgPixel & 0x0000FF)      ) / 255.0

         R = R / 12.92 if R <= 0.04045 else (( R + 0.055) / 1.055) ** 2.4
         G = G / 12.92 if G <= 0.04045 else (( G + 0.055) / 1.055) ** 2.4
         B = B / 12.92 if B <= 0.04045 else (( B + 0.055) / 1.055) ** 2.4

         Y = 0.2126 * R + 0.7152 * G + 0.0722 * B

            # If the Y is in range, then append the pixel coordinates and color value to the array
         if Y>Llo or Y<Lhi: results.append([ ic, ir, imgPixel ])

# CAVEAT: This code is entered but not tested in Python.

很有可能有一种方法可以将其矢量化,因此值得看看我上面链接的颜色科学库,因为它尽可能做到这一点

相关问题 更多 >