【问题标题】:How to correctly read an image in YCbCr mode?如何在 YCbCr 模式下正确读取图像?
【发布时间】:2020-08-17 12:45:33
【问题描述】:

我如何知道我是否在 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 已经为我完成了转换,但我无法找到它的源代码。所以我自己定义了转换函数,但我得到了不同的像素值。

【问题讨论】:

    标签: python image-processing computer-vision rgb ycbcr


    【解决方案1】:

    在最新的 scipy 版本中,imread 已弃用。但是,它使用来自PILImage.convert 来转换模式。

    详情:

    https://pillow.readthedocs.io/en/3.1.x/reference/Image.html?highlight=convert#PIL.Image.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) 函数,它给出了相同的结果。

    使用的实现:https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdprfx/b550d1b5-f7d9-4a0c-9141-b3dca9d7f525?redirectedfrom=MSDN

    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]
    
    

    【讨论】:

    • 感谢您提供的功能。有没有参考这种计算方式?还有两个额外的问题:由于 scipy.misc.imread 现在已贬值,阅读图像的最佳方式是什么?最后还有一个用于 imread 的 flatten 参数,它假设将 3 个通道展平为 1,这是怎么做的?
    • 这个我不确定,你怎么定义最好的?你可以使用 opencv imread,P​​illow open。你的意思是scipy?对于扁平化,这可能很有用:stackoverflow.com/questions/32314657/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多