4

I'm going to convert RGB image to YIQ image and viceversa. The problem is Python give me a weird image, while MATLAB shows the right one. I spent hours to figure what's wrong, but i still have no idea.

I use Python 3.5.2 with OpenCV 3.1.0 and MATLAB R2016a.

Python code for 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 code for 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 code for 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()

MATLAB code for 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

Some said that i used to convert the image to float64 before manipulates it. Already tried that, but nothing changed. I also used astype(np.uint8) to convert float64 to uint8 to avoid values outside [0..255]. In MATLAB there is no such problem.

4
  • 1
    A side note on efficient numpy coding : Loops are very slow, vectorisation is fast. So write r[:,:] = img[:,:,0] instead of for i in range(row): j in range(col): r[i,j] = img[i,j,0] if you want your program to run in a reasonable amount of time. Commented Oct 15, 2016 at 12:39
  • In python, convert the img to float before the for loops Commented Oct 15, 2016 at 12:39
  • @jadsq yeah, thank you for your advice. Didn't notice it before. Commented Oct 15, 2016 at 13:13
  • @Miki i tried it, but nothing changed. Commented Oct 15, 2016 at 13:15

1 Answer 1

0

You obviously face a saturation problem, due to some computed component exceeding the range [0,255]. Clamp the values or adjust the gain.

Then there seems to be a swapping of the components somewhere.

Sign up to request clarification or add additional context in comments.

1 Comment

Therefore, i used astype(np.uint8) to convert float64 to uint8. In MATLAB there is no such problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.