# Color Processing

## TV Space Color

### YUV

It's the basic encoding for analog TV. It is used in the NTSC and PAL. The luminance Y is compute as:

$Y=0.299\cdot R+0.587\cdot G+0.114\cdot B$

The components U and V are the difference between red or blue and the luminance weighted by a fator.

$U=0.492\cdot \left(B-Y\right)$ et $V=0.877\cdot \left(R-Y\right)$

We can also write this conversion in the following way:

$\left(\begin{array}{c}Y\\ U\\ V\end{array}\right)=\left(\begin{array}{ccc}0.299& 0.587& 0.114\\ -0.147& -0.289& 0.436\\ 0.615& -0.515& -0.1\end{array}\right)\cdot \left(\begin{array}{c}R\\ G\\ B\end{array}\right)$

The inverse transformation YUV to RGB is compute as:

$\left(\begin{array}{c}R\\ G\\ B\end{array}\right)=\left(\begin{array}{ccc}1& 0& 1.14\\ 1& -0.395& -0.581\\ 1& 2.032& 0\end{array}\right)\cdot \left(\begin{array}{c}Y\\ U\\ V\end{array}\right)$

The Matlab program :

```% conversion RGB --> YUV %normalisation des couleurs Y = 0.299*R + 0.587*G + 0.114*B  ; U = 0.492*(B-Y); V = 0.877*(R-Y); Rp= Y + 1.140*V; Gp= Y - 0.395*U -0.581*V; Bp= Y + 2.032*U ; figure(  'Name','RGB --> YUV',...             'NumberTitle','off',...             'color',[0.3137 0.3137 0.5098]); vide=zeros(ligne,colonne); subplot(331) imshow(uint8(cat(3,R,vide,vide))) title('Image R origine') subplot(334) imshow(uint8(cat(3,vide,G,vide))) title('Image G origine') subplot(337) imshow(uint8(cat(3,vide,vide,B))) title('Image B origine') subplot(332) imagesc(Y,[min(min(Y)) max(max(Y))]) colormap(gray) axis image title('Image Y') subplot(335) imagesc(U,[min(min(U)) max(max(U))]) colormap(gray) axis image title('Image U') subplot(338) imagesc(V,[min(min(V)) max(max(V))]) colormap(gray) axis image title('Image V') subplot(333) imshow(uint8(cat(3,Rp,vide,vide))) title('Image R reconstruit') subplot(336) imshow(uint8(cat(3,vide,Gp,vide))) title('Image G reconstruit') subplot(339) imshow(uint8(cat(3,vide,vide,Bp))) title('Image B reconstruit')```

An example:

### YIQ

It's the original NTSC system. The luminance Y is the same as for th YUV. I represent the inphase and Q the quadrature. U and V are rotated and mirrored thanks to the angle b. Here is the equations:

$I=-sin\left(b\right)\cdot U+cos\left(b\right)\cdot V$

et

$Q=cos\left(b\right)\cdot U+sin\left(b\right)\cdot V$

the angle b is equal to 0.576 or 33°.

We can also compute this transformation as:

$\left(\begin{array}{c}Y\\ I\\ Q\end{array}\right)=\left(\begin{array}{ccc}0.299& 0.587& 0.114\\ 0.596& -0.274& -0.322\\ 0.211& -0.523& 0.312\end{array}\right)\cdot \left(\begin{array}{c}R\\ G\\ B\end{array}\right)$

The inverse transformation is made with:

$\left(\begin{array}{c}R\\ G\\ B\end{array}\right)=\left(\begin{array}{ccc}1& 0.956& 0.621\\ 1& -0.272& -0.647\\ 1& -1.106& 1.703\end{array}\right)\cdot \left(\begin{array}{c}Y\\ I\\ Q\end{array}\right)$

The Matlab program:

```Y = 0.299*R + 0.587*G + 0.114*B  ; U = 0.492*(B-Y); V = 0.877*(R-Y); b=0.576; I = -sin(b)*U + cos(b)*V ; Q = cos(b)*U + sin(b)*V ; Rp= Y +  0.956*I +  0.621*Q; Gp= Y -  0.272 *I - 0.647*Q; Bp= Y -  1.106*I + 1.703*Q; figure(  'Name','RGB --> YIQ',...             'NumberTitle','off',...             'color',[0.3137 0.3137 0.5098]); vide=zeros(ligne,colonne); subplot(331) imshow(uint8(cat(3,R,vide,vide))) title('Image R') subplot(334) imshow(uint8(cat(3,vide,G,vide))) title('Image G') subplot(337) imshow(uint8(cat(3,vide,vide,B))) title('Image G')  subplot(332) imagesc(Y,[min(min(Y)) max(max(Y))]) colormap(gray) axis image title('Image Y') subplot(335) imagesc(I,[min(min(I)) max(max(I))]) colormap(gray) axis image title('Image I') subplot(338) imagesc(Q,[min(min(Q)) max(max(Q))]) colormap(gray) axis image title('Image Q') subplot(333) imshow(uint8(cat(3,Rp,vide,vide))) title('Image R reconstruit') subplot(336) imshow(uint8(cat(3,vide,Gp,vide))) title('Image G reconstruit') subplot(339) imshow(uint8(cat(3,vide,vide,Bp))) title('Image B  reconstruit')```

An example:

### YCbCr

This color scale is a international standard of YUV. It is used in the digital TV and in compression (JPEG). We have for the RGB to YCbCr transformation:

$Y=wr\cdot R+wg\cdot G+wb\cdot B$
$Cb=\genfrac{}{}{0.1ex}{}{0.5}{1-wb}\cdot \left(B-Y\right)$
$Cr=\genfrac{}{}{0.1ex}{}{0.5}{1-wr}\cdot \left(R-Y\right)$

where wr = 0.299, wb = 0.114 and Wc = 1 - wb - wr.
The inverse transformation YCbCr to RGB is made thanks to:

$R=Y+\genfrac{}{}{0.1ex}{}{1-wr}{0.5}\cdot Cr$
$G=Y+\genfrac{}{}{0.1ex}{}{wb\cdot \left(1-wb\right)\cdot Cb-wr\cdot \left(1-wr\right)\cdot Cr}{0.5\cdot \left(wg\right)}$
$B=Y+\genfrac{}{}{0.1ex}{}{1-wb}{0.5}\cdot Cb$

This transfomartion can also be made with the folowing matrix:

$\left(\begin{array}{c}Y\\ Cb\\ Cr\end{array}\right)=\left(\begin{array}{ccc}0.299& 0.587& 0.114\\ -0.169& -0.331& 0.5\\ 0.5& -0.419& -0.081\end{array}\right)\cdot \left(\begin{array}{c}R\\ G\\ B\end{array}\right)$
$\left(\begin{array}{c}R\\ G\\ B\end{array}\right)=\left(\begin{array}{ccc}1& 0& 1.403\\ 1& -0.344& -0.714\\ 1& 1.773& 0\end{array}\right)\cdot \left(\begin{array}{c}Y\\ \mathrm{Cb}\\ \mathrm{Cr}\end{array}\right)$

The Matlab program:

```% conversion RGB --> YCbCr %normalisation des couleurs Wr=0.299;Wb=0.114; Wg=1-Wr-Wb; Y = Wr*R + Wg*G + Wb*B  ; Cb= ( 0.5 / ( 1-Wb) ) * (B-Y); Cr= ( 0.5 / ( 1-Wr) ) * (R-Y); Rp= Y + ((1 - Wr)/0.5)*Cr; Gp= Y + (Wb*(1-Wb)*Cb - Wr*(1-Wr)*Cr)/(0.5*(1-Wb-Wr)); Bp= Y + ((1 - Wb)/0.5) * Cb; figure(  'Name','RGB --> YCbCr',...             'NumberTitle','off',...             'color',[0.3137 0.3137 0.5098]); vide=zeros(ligne,colonne); subplot(331) imshow(uint8(cat(3,R,vide,vide))) title('Image R origine') subplot(334) imshow(uint8(cat(3,vide,G,vide))) title('Image G origine') subplot(337) imshow(uint8(cat(3,vide,vide,B))) title('Image B  origine')  subplot(332) imagesc(Y,[min(min(Y)) max(max(Y))]) colormap(gray) axis image title('Image Y') subplot(335) imagesc(Cb,[min(min(Cb)) max(max(Cb))]) colormap(gray) axis image title('Image Cb') subplot(338) imagesc(Cr,[min(min(Cr)) max(max(Cr))]) colormap(gray) axis image title('Image Cr') subplot(333) imshow(uint8(cat(3,Rp,vide,vide))) title('Image R reconstruit') subplot(336) imshow(uint8(cat(3,vide,Gp,vide))) title('Image G reconstruit') subplot(339) imshow(uint8(cat(3,vide,vide,Bp))) title('Image B  reconstruit')```

An example:

### Complete Program

```clear all; close all; [filename, pathname] = uigetfile({'*.jpg;*.tif;*.png;*.gif;*.bmp','All Image Files';...           '*.*','All Files' },'mytitle',...           'C:\Work\myfile.jpg'); img = imread(filename); [ligne colonne dimension]=size(img); img=double(img); R=img(:,:,1); G=img(:,:,2); B=img(:,:,3); Imax = max(max(img));   % conversion RGB --> YUV Y = 0.299*R + 0.587*G + 0.114*B  ; U = 0.492*(B-Y); V = 0.877*(R-Y); Rp= Y + 1.140*V; Gp= Y - 0.395*U -0.581*V; Bp= Y + 2.032*U ; figure(  'Name','RGB --> YUV',...             'NumberTitle','off',...             'color',[0.3137 0.3137 0.5098]); vide=zeros(ligne,colonne); subplot(331) imshow(uint8(cat(3,R,vide,vide))) title('Image R origine') subplot(334) imshow(uint8(cat(3,vide,G,vide))) title('Image G origine') subplot(337) imshow(uint8(cat(3,vide,vide,B))) title('Image B origine') subplot(332) imagesc(Y,[min(min(Y)) max(max(Y))]) colormap(gray) axis image title('Image Y') subplot(335) imagesc(U,[min(min(U)) max(max(U))]) colormap(gray) axis image title('Image U') subplot(338) imagesc(V,[min(min(V)) max(max(V))]) colormap(gray) axis image title('Image V') subplot(333) imshow(uint8(cat(3,Rp,vide,vide))) title('Image R reconstruit') subplot(336) imshow(uint8(cat(3,vide,Gp,vide))) title('Image G reconstruit') subplot(339) imshow(uint8(cat(3,vide,vide,Bp))) title('Image B reconstruit') % conversion RGB --> YIQ Y = 0.299*R + 0.587*G + 0.114*B  ; U = 0.492*(B-Y); V = 0.877*(R-Y); b=0.576; I = -sin(b)*U + cos(b)*V ; Q = cos(b)*U + sin(b)*V ; Rp= Y +  0.956*I +  0.621*Q; Gp= Y -  0.272 *I - 0.647*Q; Bp= Y -  1.106*I + 1.703*Q; figure(  'Name','RGB --> YIQ',...             'NumberTitle','off',...             'color',[0.3137 0.3137 0.5098]); vide=zeros(ligne,colonne); subplot(331) imshow(uint8(cat(3,R,vide,vide))) title('Image R') subplot(334) imshow(uint8(cat(3,vide,G,vide))) title('Image G') subplot(337) imshow(uint8(cat(3,vide,vide,B))) title('Image G')  subplot(332) imagesc(Y,[min(min(Y)) max(max(Y))]) colormap(gray) axis image title('Image Y') subplot(335) imagesc(I,[min(min(I)) max(max(I))]) colormap(gray) axis image title('Image I') subplot(338) imagesc(Q,[min(min(Q)) max(max(Q))]) colormap(gray) axis image title('Image Q') subplot(333) imshow(uint8(cat(3,Rp,vide,vide))) title('Image R reconstruit') subplot(336) imshow(uint8(cat(3,vide,Gp,vide))) title('Image G reconstruit') subplot(339) imshow(uint8(cat(3,vide,vide,Bp))) title('Image B  reconstruit') % conversion RGB --> YCbCr Wr=0.299;Wb=0.114; Wg=1-Wr-Wb; Y = Wr*R + Wg*G + Wb*B  ; Cb= ( 0.5 / ( 1-Wb) ) * (B-Y); Cr= ( 0.5 / ( 1-Wr) ) * (R-Y); Rp= Y + ((1 - Wr)/0.5)*Cr; Gp= Y + (Wb*(1-Wb)*Cb - Wr*(1-Wr)*Cr)/(0.5*(1-Wb-Wr)); Bp= Y + ((1 - Wb)/0.5) * Cb; figure(  'Name','RGB --> YCbCr',...             'NumberTitle','off',...             'color',[0.3137 0.3137 0.5098]); vide=zeros(ligne,colonne); subplot(331) imshow(uint8(cat(3,R,vide,vide))) title('Image R origine') subplot(334) imshow(uint8(cat(3,vide,G,vide))) title('Image G origine') subplot(337) imshow(uint8(cat(3,vide,vide,B))) title('Image B  origine')  subplot(332) imagesc(Y,[min(min(Y)) max(max(Y))]) colormap(gray) axis image title('Image Y') subplot(335) imagesc(Cb,[min(min(Cb)) max(max(Cb))]) colormap(gray) axis image title('Image Cb') subplot(338) imagesc(Cr,[min(min(Cr)) max(max(Cr))]) colormap(gray) axis image title('Image Cr') subplot(333) imshow(uint8(cat(3,Rp,vide,vide))) title('Image R reconstruit') subplot(336) imshow(uint8(cat(3,vide,Gp,vide))) title('Image G reconstruit') subplot(339) imshow(uint8(cat(3,vide,vide,Bp))) title('Image B  reconstruit')```