参考:
在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