在 uint8 中将 RGB 转换为 YIQ 颜色模式时出现问题,反之亦然
Problem during converting RGB to YIQ color mode and vice versa in uint8
我有一个矩阵,它是一个包含 BGR 值的图像。这是在问题
中被切片以使其更短的图像
img = [[[72, 63, 0],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[74, 65, 2],
[72, 63, 0],
[71, 62, 0]]]
我已经成功制作了一个将 BGR 值转换为 YIQ 的函数,但是这个函数没有将 YIQ 值转换为 uint8。它使 I 和 Q 值可以为负值
import numpy as np
def RGB2YIQ(img):
BGR = img.copy().astype(float)
R = BGR[:,:,2]
G = BGR[:,:,1]
B = BGR[:,:,0]
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
I = (0.59590059 * R) + (-0.27455667 * G) + (-0.32134392 * B)
Q = (0.21153661 * R) + (-0.52273617 * G) + (0.31119955 * B)
YIQ = (np.dstack((Y,I,Q))).astype(int)
return YIQ
>>> RGB2YIQ(img)
>>> array([[[ 45, -40, -10],
[ 44, -39, -10],
[ 43, -39, -10]],
[[ 46, -40, -10],
[ 44, -39, -10],
[ 43, -39, -10]],
[[ 46, -40, -10],
[ 45, -40, -10],
[ 44, -39, -10]],
[[ 46, -40, -10],
[ 45, -40, -10],
[ 44, -39, -10]],
[[ 47, -40, -10],
[ 45, -40, -10],
[ 44, -39, -10]]])
我也已经将转换回 RGB,同样工作正常
def YIQ2RGB(img):
YIQ = img.copy().astype(int)
Y = YIQ[:,:,0]
I = YIQ[:,:,1]
Q = YIQ[:,:,2]
R = (1 * Y) + (0.95598634 * I) + (0.6208248 * Q)
G = (1 * Y) + (-0.27201283 * I)) + (-0.64720424 * Q)
B = (1 * Y) + (-1.10674021 * I) + (1.70423049 * Q)
RGB = (np.dstack((R,G,B))).astype(np.uint8)
return RGB
>>>YIQ2RGB(img)
>>>array([[[ 0, 62, 72],
[ 0, 61, 70],
[ 0, 60, 69]],
[[ 1, 63, 73],
[ 0, 61, 70],
[ 0, 60, 69]],
[[ 1, 63, 73],
[ 0, 62, 72],
[ 0, 61, 70]],
[[ 1, 63, 73],
[ 0, 62, 72],
[ 0, 61, 70]],
[[ 2, 64, 74],
[ 0, 62, 72],
[ 0, 61, 70]]], dtype=uint8)
当我尝试将 YIQ 数组转换为 uint8 类型然后将其转换回 RGB 时出现问题。我试图将 128 添加到 I 和 Q 通道中,所以我将 RGB2YIQ 函数修改为 return uint8 类型数组
import numpy as np
def RGB2YIQ(img):
BGR = img.copy().astype(float)
R = BGR[:,:,2]
G = BGR[:,:,1]
B = BGR[:,:,0]
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
I = (0.59590059 * R) + (-0.27455667 * G) + (-0.32134392 * B)
Q = (0.21153661 * R) + (-0.52273617 * G) + (0.31119955 * B)
YIQ = (np.dstack((Y,I + 128,Q + 128))).astype(np.uint8)
return YIQ
>>> RGB2YIQ(img)
>>> array([[[ 45, 87, 117],
[ 44, 88, 117],
[ 43, 88, 117]],
[[ 46, 87, 117],
[ 44, 88, 117],
[ 43, 88, 117]],
[[ 46, 87, 117],
[ 45, 87, 117],
[ 44, 88, 117]],
[[ 46, 87, 117],
[ 45, 87, 117],
[ 44, 88, 117]],
[[ 47, 87, 117],
[ 45, 87, 117],
[ 44, 88, 117]]], dtype=uint8)
但是当我修改 YIQ2RGB 函数并尝试它时,它给了我不同的 Y 值,这很奇怪,因为我唯一改变的是加 128 并减去它,但它只给我一个通道的不同值.
def YIQ2RGB(img):
YIQ = img.copy().astype(int)
Y = YIQ[:,:,0]
I = YIQ[:,:,1] - 128
Q = YIQ[:,:,2] - 128
R = (1 * Y) + (0.95598634 * I) + (0.6208248 * Q)
G = (1 * Y) + (-0.27201283 * I) + (-0.64720424 * Q)
B = (1 * Y) + (-1.10674021 * I) + (1.70423049 * Q)
RGB = (np.dstack((R,G,B))).astype(np.uint8)
return RGB
>>>YIQ2RGB(img)
>>>array([[[255, 63, 71],
[255, 61, 69],
[254, 60, 68]],
[[ 0, 64, 72],
[255, 61, 69],
[254, 60, 68]],
[[ 0, 64, 72],
[255, 63, 71],
[255, 61, 69]],
[[ 0, 64, 72],
[255, 63, 71],
[255, 61, 69]],
[[ 0, 65, 73],
[255, 63, 71],
[255, 61, 69]]], dtype=uint8)
我怀疑这是因为类型转换问题,但我在 np.uint8 之间来回切换
和 int,仍然给我相同的结果
基本问题只是虚幻的bug...
以下代码行:
R = BGR[:,:,2]
G = BGR[:,:,1]
B = BGR[:,:,0]
应该是:
R = BGR[:,:,0]
G = BGR[:,:,1]
B = BGR[:,:,2]
其他问题:
- 在投射到
uint8
之前,您需要将 RGB
的范围裁剪到 [0, 255]。
- 为了更准确,您可以在从
float
转换为整数之前使用 np.round
。
这里是你的代码的一个稍微修改的版本:
import numpy as np
def RGB2YIQ(img):
BGR = img.copy().astype(float)
R = BGR[:,:,0]
G = BGR[:,:,1]
B = BGR[:,:,2]
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
I = (0.59590059 * R) + (-0.27455667 * G) + (-0.32134392 * B)
Q = (0.21153661 * R) + (-0.52273617 * G) + (0.31119955 * B)
YIQ = np.round(np.dstack((Y,I + 128,Q + 128))).astype(np.uint8)
return YIQ
def YIQ2RGB(img):
YIQ = img.copy().astype(float)
Y = YIQ[:,:,0]
I = YIQ[:,:,1] - 128
Q = YIQ[:,:,2] - 128
R = (1 * Y) + (0.95598634 * I) + (0.6208248 * Q)
G = (1 * Y) + (-0.27201283 * I) + (-0.64720424 * Q)
B = (1 * Y) + (-1.10674021 * I) + (1.70423049 * Q)
RGB = np.round(np.clip(np.dstack((R,G,B)), 0, 255)).astype(np.uint8)
return RGB
img = np.array([[[72, 63, 0],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[74, 65, 2],
[72, 63, 0],
[71, 62, 0]]], np.uint8)
yiq_img = RGB2YIQ(img)
rgb_img = YIQ2RGB(yiq_img)
print(rgb_img.astype(np.int16) - img.astype(np.int16)) # Print the difference.
结果:
[[[1 1 0]
[0 0 1]
[0 0 0]]
[[1 1 0]
[0 0 1]
[0 0 0]]
[[1 1 0]
[1 1 0]
[0 0 1]]
[[1 1 0]
[1 1 0]
[0 0 1]]
[[1 1 0]
[1 1 0]
[0 0 1]]]
最大差值为 1(由于四舍五入而不为零)。
我有一个矩阵,它是一个包含 BGR 值的图像。这是在问题
中被切片以使其更短的图像img = [[[72, 63, 0],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[74, 65, 2],
[72, 63, 0],
[71, 62, 0]]]
我已经成功制作了一个将 BGR 值转换为 YIQ 的函数,但是这个函数没有将 YIQ 值转换为 uint8。它使 I 和 Q 值可以为负值
import numpy as np
def RGB2YIQ(img):
BGR = img.copy().astype(float)
R = BGR[:,:,2]
G = BGR[:,:,1]
B = BGR[:,:,0]
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
I = (0.59590059 * R) + (-0.27455667 * G) + (-0.32134392 * B)
Q = (0.21153661 * R) + (-0.52273617 * G) + (0.31119955 * B)
YIQ = (np.dstack((Y,I,Q))).astype(int)
return YIQ
>>> RGB2YIQ(img)
>>> array([[[ 45, -40, -10],
[ 44, -39, -10],
[ 43, -39, -10]],
[[ 46, -40, -10],
[ 44, -39, -10],
[ 43, -39, -10]],
[[ 46, -40, -10],
[ 45, -40, -10],
[ 44, -39, -10]],
[[ 46, -40, -10],
[ 45, -40, -10],
[ 44, -39, -10]],
[[ 47, -40, -10],
[ 45, -40, -10],
[ 44, -39, -10]]])
我也已经将转换回 RGB,同样工作正常
def YIQ2RGB(img):
YIQ = img.copy().astype(int)
Y = YIQ[:,:,0]
I = YIQ[:,:,1]
Q = YIQ[:,:,2]
R = (1 * Y) + (0.95598634 * I) + (0.6208248 * Q)
G = (1 * Y) + (-0.27201283 * I)) + (-0.64720424 * Q)
B = (1 * Y) + (-1.10674021 * I) + (1.70423049 * Q)
RGB = (np.dstack((R,G,B))).astype(np.uint8)
return RGB
>>>YIQ2RGB(img)
>>>array([[[ 0, 62, 72],
[ 0, 61, 70],
[ 0, 60, 69]],
[[ 1, 63, 73],
[ 0, 61, 70],
[ 0, 60, 69]],
[[ 1, 63, 73],
[ 0, 62, 72],
[ 0, 61, 70]],
[[ 1, 63, 73],
[ 0, 62, 72],
[ 0, 61, 70]],
[[ 2, 64, 74],
[ 0, 62, 72],
[ 0, 61, 70]]], dtype=uint8)
当我尝试将 YIQ 数组转换为 uint8 类型然后将其转换回 RGB 时出现问题。我试图将 128 添加到 I 和 Q 通道中,所以我将 RGB2YIQ 函数修改为 return uint8 类型数组
import numpy as np
def RGB2YIQ(img):
BGR = img.copy().astype(float)
R = BGR[:,:,2]
G = BGR[:,:,1]
B = BGR[:,:,0]
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
I = (0.59590059 * R) + (-0.27455667 * G) + (-0.32134392 * B)
Q = (0.21153661 * R) + (-0.52273617 * G) + (0.31119955 * B)
YIQ = (np.dstack((Y,I + 128,Q + 128))).astype(np.uint8)
return YIQ
>>> RGB2YIQ(img)
>>> array([[[ 45, 87, 117],
[ 44, 88, 117],
[ 43, 88, 117]],
[[ 46, 87, 117],
[ 44, 88, 117],
[ 43, 88, 117]],
[[ 46, 87, 117],
[ 45, 87, 117],
[ 44, 88, 117]],
[[ 46, 87, 117],
[ 45, 87, 117],
[ 44, 88, 117]],
[[ 47, 87, 117],
[ 45, 87, 117],
[ 44, 88, 117]]], dtype=uint8)
但是当我修改 YIQ2RGB 函数并尝试它时,它给了我不同的 Y 值,这很奇怪,因为我唯一改变的是加 128 并减去它,但它只给我一个通道的不同值.
def YIQ2RGB(img):
YIQ = img.copy().astype(int)
Y = YIQ[:,:,0]
I = YIQ[:,:,1] - 128
Q = YIQ[:,:,2] - 128
R = (1 * Y) + (0.95598634 * I) + (0.6208248 * Q)
G = (1 * Y) + (-0.27201283 * I) + (-0.64720424 * Q)
B = (1 * Y) + (-1.10674021 * I) + (1.70423049 * Q)
RGB = (np.dstack((R,G,B))).astype(np.uint8)
return RGB
>>>YIQ2RGB(img)
>>>array([[[255, 63, 71],
[255, 61, 69],
[254, 60, 68]],
[[ 0, 64, 72],
[255, 61, 69],
[254, 60, 68]],
[[ 0, 64, 72],
[255, 63, 71],
[255, 61, 69]],
[[ 0, 64, 72],
[255, 63, 71],
[255, 61, 69]],
[[ 0, 65, 73],
[255, 63, 71],
[255, 61, 69]]], dtype=uint8)
我怀疑这是因为类型转换问题,但我在 np.uint8 之间来回切换 和 int,仍然给我相同的结果
基本问题只是虚幻的bug...
以下代码行:
R = BGR[:,:,2]
G = BGR[:,:,1]
B = BGR[:,:,0]
应该是:
R = BGR[:,:,0]
G = BGR[:,:,1]
B = BGR[:,:,2]
其他问题:
- 在投射到
uint8
之前,您需要将RGB
的范围裁剪到 [0, 255]。 - 为了更准确,您可以在从
float
转换为整数之前使用np.round
。
这里是你的代码的一个稍微修改的版本:
import numpy as np
def RGB2YIQ(img):
BGR = img.copy().astype(float)
R = BGR[:,:,0]
G = BGR[:,:,1]
B = BGR[:,:,2]
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
I = (0.59590059 * R) + (-0.27455667 * G) + (-0.32134392 * B)
Q = (0.21153661 * R) + (-0.52273617 * G) + (0.31119955 * B)
YIQ = np.round(np.dstack((Y,I + 128,Q + 128))).astype(np.uint8)
return YIQ
def YIQ2RGB(img):
YIQ = img.copy().astype(float)
Y = YIQ[:,:,0]
I = YIQ[:,:,1] - 128
Q = YIQ[:,:,2] - 128
R = (1 * Y) + (0.95598634 * I) + (0.6208248 * Q)
G = (1 * Y) + (-0.27201283 * I) + (-0.64720424 * Q)
B = (1 * Y) + (-1.10674021 * I) + (1.70423049 * Q)
RGB = np.round(np.clip(np.dstack((R,G,B)), 0, 255)).astype(np.uint8)
return RGB
img = np.array([[[72, 63, 0],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[71, 62, 0],
[70, 61, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[73, 64, 1],
[72, 63, 0],
[71, 62, 0]],
[[74, 65, 2],
[72, 63, 0],
[71, 62, 0]]], np.uint8)
yiq_img = RGB2YIQ(img)
rgb_img = YIQ2RGB(yiq_img)
print(rgb_img.astype(np.int16) - img.astype(np.int16)) # Print the difference.
结果:
[[[1 1 0]
[0 0 1]
[0 0 0]]
[[1 1 0]
[0 0 1]
[0 0 0]]
[[1 1 0]
[1 1 0]
[0 0 1]]
[[1 1 0]
[1 1 0]
[0 0 1]]
[[1 1 0]
[1 1 0]
[0 0 1]]]
最大差值为 1(由于四舍五入而不为零)。