【问题标题】:Python: Convert image from RGB to YDbDr color spacePython:将图像从 RGB 转换为 YDbDr 颜色空间
【发布时间】:2021-03-01 16:55:29
【问题描述】:

尝试根据公式将图像从RGB色彩空间转换为YDbDr色彩空间:

Y = 0.299R + 0.587G + 0.114B

Db = -0.45R - 0.883G +1.333B

Dr = -1.333R + 1.116G + 0.217B

使用下面的代码,我试图只显示 Y 通道,它应该是灰度图像,但我一直得到的图像都是蓝色的:

import numpy as np
from PIL import Image
import cv2
import matplotlib.pyplot as plt

img = cv2.imread("./pics/Slike_modela/Test/Proba/1_Color.png")
new_img = []
for row in img:
    new_row = []
    for pixel in row:
        Y = 0.299*pixel[2]+0.587*pixel[1]+0.114*pixel[0]
        Db = -0.45*pixel[2]-0.883*pixel[1]+1.333*pixel[0]
        Dr = -1.333*pixel[2]+1.116*pixel[1]+0.217*pixel[0]
        new_pixel = [Y, Db, Dr]
        new_row.append(new_pixel)
    new_img.append(new_row)

new_img_arr = np.array(new_img)
new_img_arr_y = new_img_arr.copy()
new_img_arr_y[:,:,1] = 0
new_img_arr_y[:,:,2] = 0
print (new_img_arr_y)
cv2.imshow("y image", new_img_arr_y) 
key = cv2.waitKey(0)

在打印结果数组时,我会根据公式和正确的数组形状看到正确的数字。

我的错误是什么?如何得到Y通道图像即灰度图像?

【问题讨论】:

  • 如果你想要灰度,你应该使用new_pixel = [Y, Y, Y]:所有值都应该相同。
  • 你能解释一下为什么吗?我尝试了所有三个 Y,但它仍然是一样的。当我尝试使用 RGB 图像时,我可以轻松地只显示一个通道,例如红色通道,只需将像素的蓝色和绿色值设置为 0。
  • 如果您设置所有 Y,您应该删除其他字节的零设置。灰度意味着所有颜色都应该具有相同的强度(黑色和白色都具有相同的强度)。
  • 你能告诉我 BGR 中的 [255,0,0] 是什么颜色吗?如果您将 G、R 通道设置为 0,会发生什么?要么制作单通道图像,要么将三个通道设置为相同的值
  • 你是对的,将所有三个像素通道设置为 Y,它显示的是灰度。虽然起初它显示的是通过修改解决的白色图像:cv2.imshow("image y", np.uint8(new_img_arr_y))。 [255,0,0] G 和 R 设置为 0 是纯蓝色图像。谢谢!

标签: python image opencv rgb


【解决方案1】:

当使用 Python 处理图像时,你真的,真的应该尽量避免:

  • 将图像视为列表并附加数百万像素,每个像素都会创建一个全新的对象并占用空间来管理

  • 使用for 循环处理图像,非常慢

处理这两种情况的更好方法是使用Numpy 或其他矢量化代码库或技术。这就是 OpenCVwandscikit-image 将图像作为 Numpy 数组打开和处理的原因。

所以,你基本上想用一组 3 个权重对颜色通道进行点积:

import cv2
import numpy as np

# Load image
im = cv2.imread('paddington.png', cv2.IMREAD_COLOR)

# Calculate Y using Numpy "dot()"
Y = np.dot(im[...,:3], [0.114, 0.587, 0.299]).astype(np.uint8)

就是这样。

【讨论】: