2016-10-15 3 views
4

Я собираюсь преобразовать изображение RGB в изображение YIQ и наоборот. Проблема в том, что Python дает мне странное изображение, в то время как MATLAB показывает правильный. Я потратил часы, чтобы понять, что случилось, но я до сих пор не знаю.Различные цветовые результаты между Python OpenCV и MATLAB

Я использую Python 3.5.2 с OpenCV 3.1.0 и MATLAB R2016a.

код Python для RGB2YIQ:

import cv2 as cv 
import numpy as np 

def rgb2yiq(img): 
    row, col, ch = img.shape 
    Y = np.zeros((row,col)) 
    I = np.zeros((row,col)) 
    Q = np.zeros((row,col)) 
    for i in range(row): 
     for j in range(col): 
     Y[i,j] = 0.299 * img[i,j,2] + 0.587 * img[i,j,1] + 0.114 * img[i,j,0] 
     I[i,j] = 0.596 * img[i,j,2] - 0.274 * img[i,j,1] - 0.322 * img[i,j,0] 
     Q[i,j] = 0.211 * img[i,j,2] - 0.523 * img[i,j,1] + 0.312 * img[i,j,0] 
    yiq = cv.merge((Y,I,Q)) 
    return yiq.astype(np.uint8) 

def main(): 
    img = cv.imread("C:/Users/Kadek/Documents/MATLAB/peppers.jpg") 
    img = rgb2yiq(img) 
    cv.imwrite("YIQ.jpg",img) 
    cv.namedWindow('Image', cv.WINDOW_NORMAL) 
    cv.imshow('Image', img) 
    cv.waitKey(0) 
    cv.destroyAllWindows() 

main() 

код MATLAB для RGB2YIQ:

img = imread('peppers.jpg'); 
[row col ch] = size(img); 

for x=1:row 
    for y=1:col 
     Y(x,y) = 0.299 * img(x,y,1) + 0.587 * img(x,y,2) + 0.114 * img(x,y,3); 
     I(x,y) = 0.596 * img(x,y,1) - 0.274 * img(x,y,2) - 0.322 * img(x,y,3); 
     Q(x,y) = 0.211 * img(x,y,1) - 0.523 * img(x,y,2) + 0.312 * img(x,y,3); 
    end 
end 

yiq(:,:,1) = Y; 
yiq(:,:,2) = I; 
yiq(:,:,3) = Q; 

figure, imshow(yiq); 

Result for RGB2YIQ

код Python для YIQ2RGB:

import cv2 as cv 
import numpy as np 

def yiq2rgb(img): 
    row, col, ch = img.shape 
    r = np.zeros((row,col)) 
    g = np.zeros((row,col)) 
    b = np.zeros((row,col)) 
    for i in range(row): 
     for j in range(col): 
     r[i,j] = img[i,j,0] * 1.0 + img[i,j,1] * 0.9562 + img[i,j,2] * 0.6214 
     g[i,j] = img[i,j,0] * 1.0 - img[i,j,1] * 0.2727 - img[i,j,2] * 0.6468 
     b[i,j] = img[i,j,0] * 1.0 - img[i,j,1] * 1.1037 + img[i,j,2] * 1.7006 
    rgb = cv.merge((b,g,r)) 
    return rgb.astype(np.uint8) 

def main(): 
    img = cv.imread("YIQ.jpg") 
    img = yiq2rgb(img) 
    cv.imwrite("test.jpg",img) 
    cv.namedWindow('Image', cv.WINDOW_NORMAL) 
    cv.imshow('Image', img) 
    cv.waitKey(0) 
    cv.destroyAllWindows() 

main() 

M ATLAB код YIQ2RGB:

img = imread('YIQ.jpg'); 
[row col ch] = size(img); 

for x=1:row 
    for y=1:col 
     R(x,y) = 1.0 * img(x,y,1) + 0.9562 * img(x,y,2) + 0.6214 * img(x,y,3); 
     G(x,y) = 1.0 * img(x,y,1) - 0.2727 * img(x,y,2) - 0.6468 * img(x,y,3); 
     B(x,y) = 1.0 * img(x,y,1) - 1.1037 * img(x,y,2) + 1.7006 * img(x,y,3); 
    end 
end 

rgb(:,:,1) = R; 
rgb(:,:,2) = G; 
rgb(:,:,3) = B; 

imwrite(rgb,'YIQ2RGB.jpg'); 

figure, imshow(rgb); 

Result for YIQ2RGB

Некоторые говорили, что я использовал, чтобы преобразовать изображение в float64 перед тем манипулирует его. Уже пробовал это, но ничего не изменилось. Я также использовал astype (np.uint8) для преобразования float64 в uint8, чтобы избежать значений вне [0..255]. В MATLAB такой проблемы нет.

+1

Замечание об эффективном кодировании numpy: * Циклы очень медленные, векторизация быстрая *. Поэтому напишите 'r [:,:] = img [:,:, 0]' вместо 'for i в диапазоне (строка): j в диапазоне (col): r [i, j] = img [i, j, 0] ', если вы хотите, чтобы ваша программа выполнялась в разумные сроки. – jadsq

+0

В python преобразуйте img в float перед циклами for – Miki

+0

@jadsq да, спасибо за ваш совет. Раньше этого не замечал. –

ответ

0

Вы, очевидно, сталкиваетесь с проблемой насыщения из-за некоторого вычисленного компонента, превышающего диапазон [0,255]. Закрепите значения или отрегулируйте коэффициент усиления.

Тогда, кажется, есть замена компонентов.

+0

Поэтому я использовал astype (np.uint8) для преобразования float64 в uint8. В MATLAB такой проблемы нет. –