如何在 YCbCr 模式下正确读取图像?
How to correctly read an image in YCbCr mode?
如何知道我是否正确读取了 YCbCr 模式下的 PNG 图片?我得到了不同的像素值,这令人困惑。
def convert_rgb_to_ycbcr(img):
y = 16. + (64.738 * img[:, :, 0] + 129.057 * img[:, :, 1] + 25.064 * img[:, :, 2]) / 255.
cb = 128. + (-37.945 * img[:, :, 0] - 74.494 * img[:, :, 1] + 112.439 * img[:, :, 2]) / 255.
cr = 128. + (112.439 * img[:, :, 0] - 94.154 * img[:, :, 1] - 18.285 * img[:, :, 2]) / 255.
return np.array([y, cb, cr]).transpose([1, 2, 0])
# method 1 - read as YCbCr directly
img = scipy.misc.imread(path, mode='YCbCr').astype(np.float)
print(img[0, :5, 0])
# returns [32. 45. 68. 78. 92.]
# method 2 - read as RGB and convert RGB to YCbCr
img = scipy.misc.imread(path, mode='RGB').astype(np.float)
img = convert_rgb_to_ycbcr(img)
print(img[0, :5, 0])
# returns[44.0082902 55.04281961 75.1105098 83.57022745 95.44837255]
我想使用方法 1,因为 scipy 已经为我完成了转换,但我找不到它的源代码。所以我自己定义了转换函数,但我得到了不同的像素值。
在最新的 scipy 版本中,imread
已弃用。但是,它使用 PIL
中的 Image.convert
来转换模式。
详情:
https://pillow.readthedocs.io/en/3.1.x/handbook/concepts.html#concept-modes
https://github.com/scipy/scipy/blob/v0.18.0/scipy/misc/pilutil.py#L103-L155
我更改了您的 convert_rgb_to_ycbcr(img)
函数,它给出了相同的结果。
Conversion formula from RGB to YCbCr
import scipy.misc # scipy 1.1.0
import numpy as np
def convert_rgb_to_ycbcr(im):
xform = np.array([[.299, .587, .114], [-.1687, -.3313, .5], [.5, -.4187, -.0813]])
ycbcr = im.dot(xform.T)
ycbcr[:,:,[1,2]] += 128
return np.uint8(ycbcr)
# method 1 - read as YCbCr directly
img = scipy.misc.imread('test.jpg', mode='YCbCr').astype(np.float)
print(img[0, :5, 0])
# returns [32. 45. 68. 78. 92.]
# method 2 - read as RGB and convert RGB to YCbCr
img = scipy.misc.imread('test.jpg', mode='RGB').astype(np.float)
img = convert_rgb_to_ycbcr(img)
print(img[0, :5, 0])
[165. 165. 165. 166. 167.]
[165 165 165 166 167]
如何知道我是否正确读取了 YCbCr 模式下的 PNG 图片?我得到了不同的像素值,这令人困惑。
def convert_rgb_to_ycbcr(img):
y = 16. + (64.738 * img[:, :, 0] + 129.057 * img[:, :, 1] + 25.064 * img[:, :, 2]) / 255.
cb = 128. + (-37.945 * img[:, :, 0] - 74.494 * img[:, :, 1] + 112.439 * img[:, :, 2]) / 255.
cr = 128. + (112.439 * img[:, :, 0] - 94.154 * img[:, :, 1] - 18.285 * img[:, :, 2]) / 255.
return np.array([y, cb, cr]).transpose([1, 2, 0])
# method 1 - read as YCbCr directly
img = scipy.misc.imread(path, mode='YCbCr').astype(np.float)
print(img[0, :5, 0])
# returns [32. 45. 68. 78. 92.]
# method 2 - read as RGB and convert RGB to YCbCr
img = scipy.misc.imread(path, mode='RGB').astype(np.float)
img = convert_rgb_to_ycbcr(img)
print(img[0, :5, 0])
# returns[44.0082902 55.04281961 75.1105098 83.57022745 95.44837255]
我想使用方法 1,因为 scipy 已经为我完成了转换,但我找不到它的源代码。所以我自己定义了转换函数,但我得到了不同的像素值。
在最新的 scipy 版本中,imread
已弃用。但是,它使用 PIL
中的 Image.convert
来转换模式。
详情:
https://pillow.readthedocs.io/en/3.1.x/handbook/concepts.html#concept-modes
https://github.com/scipy/scipy/blob/v0.18.0/scipy/misc/pilutil.py#L103-L155
我更改了您的 convert_rgb_to_ycbcr(img)
函数,它给出了相同的结果。
Conversion formula from RGB to YCbCr
import scipy.misc # scipy 1.1.0
import numpy as np
def convert_rgb_to_ycbcr(im):
xform = np.array([[.299, .587, .114], [-.1687, -.3313, .5], [.5, -.4187, -.0813]])
ycbcr = im.dot(xform.T)
ycbcr[:,:,[1,2]] += 128
return np.uint8(ycbcr)
# method 1 - read as YCbCr directly
img = scipy.misc.imread('test.jpg', mode='YCbCr').astype(np.float)
print(img[0, :5, 0])
# returns [32. 45. 68. 78. 92.]
# method 2 - read as RGB and convert RGB to YCbCr
img = scipy.misc.imread('test.jpg', mode='RGB').astype(np.float)
img = convert_rgb_to_ycbcr(img)
print(img[0, :5, 0])
[165. 165. 165. 166. 167.]
[165 165 165 166 167]