Преобразование цветового пространства YCbCr в RGB

Я экспериментирую со сжатием JPEG, используя python. Я загружаю изображение в формате tiff и сохраняю его как массив numpy uint8 RGB. Я делал это для отображения цвета.

def rgb2ycbcr(im):
    cbcr = np.empty_like(im)
    r = im[:,:,0]
    g = im[:,:,1]
    b = im[:,:,2]
    # Y
    cbcr[:,:,0] = .299 * r + .587 * g + .114 * b
    # Cb
    cbcr[:,:,1] = 128 - .169 * r - .331 * g + .5 * b
    # Cr
    cbcr[:,:,2] = 128 + .5 * r - .419 * g - .081 * b
    return np.uint8(cbcr)

def ycbcr2rgb(im):
    rgb = np.empty_like(im)
    y   = im[:,:,0]
    cb  = im[:,:,1] - 128
    cr  = im[:,:,2] - 128
    # R
    rgb[:,:,0] = y + 1.402 * cr
    # G
    rgb[:,:,1] = y - .34414 * cb - .71414 * cr
    # B
    rgb[:,:,2] = y + 1.772 * cb
    return np.uint8(rgb)

Я сделал простое преобразование RGB в YCbCr с последующим обратным преобразованием.

img = rgb2ycbcr(img)
imshow(img)
img = ycbcr2rgb(img)
imshow(img)

Я получил эти два выходных изображения как выход YCbCr и RGB после преобразования цветового пространства. YCbCr RGB

Кажется, что-то не так с моим преобразованием цвета, и я не могу понять, что не так. Я использовал преобразование цветового пространства JPEG, предоставленное Википедией. Спасибо вам за помощь.


person yc2986    schedule 20.01.2016    source источник


Ответы (1)


Вы должны делать промежуточные вычисления с плавающей запятой. Постеризация должна вас насторожить; у вас много "горячих" (насыщенных) пикселей.

def rgb2ycbcr(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)

def ycbcr2rgb(im):
    xform = np.array([[1, 0, 1.402], [1, -0.34414, -.71414], [1, 1.772, 0]])
    rgb = im.astype(np.float)
    rgb[:,:,[1,2]] -= 128
    rgb = rgb.dot(xform.T)
    np.putmask(rgb, rgb > 255, 255)
    np.putmask(rgb, rgb < 0, 0)
    return np.uint8(rgb)
person Emre    schedule 21.01.2016
comment
вопрос, который я использую выше, чтобы преобразовать цветное изображение png в формате (1000, 800, 3). Но тогда rgb2ycbcr возвращает форму [1000, 3] вместо [1000,800]. Я сомневаюсь, что я делаю неправильно, потому что ответ помечен как правильный. - person partizanos; 25.05.2019
comment
@emre, спасибо за ваш ответ, хотел знать, почему вы умножаете точку на транспозицию xform, а не только на xform - person ozmank; 09.11.2019