参考:
在Python中正确地将RGB转换成YCbCr
Python中rgb与ycbcr互转
# ITU-R BT.601
# https://en.wikipedia.org/wiki/YCbCr
# RGB -> YCbCr
def rgb2ycbcr(rgb):
m = np.array([[ 65.481, 128.553, 24.966],
[-37.797, -74.203, 112],
[ 112, -93.786, -18.214]])
shape = rgb.shape
if len(shape) == 3:
rgb = rgb.reshape((shape[0] * shape[1], 3))
ycbcr = np.dot(rgb, m.transpose() / 255.)
ycbcr[:,0] += 16.
ycbcr[:,1:] += 128.
return ycbcr.reshape(shape)
# ITU-R BT.601
# https://en.wikipedia.org/wiki/YCbCr
# YUV -> RGB
def ycbcr2rgb(ycbcr):
m = np.array([[ 65.481, 128.553, 24.966],
[-37.797, -74.203, 112],
[ 112, -93.786, -18.214]])
shape = ycbcr.shape
if len(shape) == 3:
ycbcr = ycbcr.reshape((shape[0] * shape[1], 3))
rgb = copy.deepcopy(ycbcr)
rgb[:,0] -= 16.
rgb[:,1:] -= 128.
rgb = np.dot(rgb, np.linalg.inv(m.transpose()) * 255.)
return rgb.clip(0, 255).reshape(shape)
mat = np.array(
[[ 65.481, 128.553, 24.966 ],
[-37.797, -74.203, 112.0 ],
[ 112.0, -93.786, -18.214]])
mat_inv = np.linalg.inv(mat)
offset = np.array([16, 128, 128])
def rgb2ycbcr(rgb_img):
ycbcr_img = np.zeros(rgb_img.shape)
for x in range(rgb_img.shape[0]):
for y in range(rgb_img.shape[1]):
ycbcr_img[x, y, :] = np.round(np.dot(mat, rgb_img[x, y, :] * 1.0 / 255) + offset)
return ycbcr_img
def ycbcr2rgb(ycbcr_img):
rgb_img = np.zeros(ycbcr_img.shape, dtype=np.uint8)
for x in range(ycbcr_img.shape[0]):
for y in range(ycbcr_img.shape[1]):
[r, g, b] = ycbcr_img[x,y,:]
rgb_img[x, y, :] = np.maximum(0, np.minimum(255, np.round(np.dot(mat_inv, ycbcr_img[x, y, :] - offset) * 255.0)))
return rgb_img