Search code examples
matlabrgbyuv

how to convert RGB to YUV in interger and then restore


i want to convert a RGB picture to YUV,and the restore it .but when i calculate in MATLAB,i found The picture isn't quite true to the original. here is my Operation in matlab ! here is my code:

%M file
clear all;  
clc;  
RGB = imread('11111.bmp');  
figure;imshow(RGB);

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

Y0= 0.256788*R + 0.504129*G + 0.097906*B +  16;
U0=-0.148223*R - 0.290993*G + 0.439216*B + 128;
V0= 0.439216*R - 0.367788*G - 0.071427*B + 128;
Y= uint8(min(255,max(0,Y0)));% i want 8 bit YUV
U= uint8(min(255,max(0,U0)));
V= uint8(min(255,max(0,V0)));
RGB1R=Y+1.14 *V;
RGB1G=Y-0.39 *U-0.58*V;
RGB1B=Y+2.03*U;
RGB1=cat(3, RGB1R, RGB1G, RGB1B);
figure; imshow(RGB1);  
%M file

it should point out that the image is capsule endoscopy image.you could get it in wwww.gastrolab.net .i want the YUV is 8 bits interger,could anybody help me??


Solution

  • To convert between RGB and YCbCr, MATLAB offers the functions rgb2ycbcr and ycbcr2rgb. YCbCr and YUV are then related by

    Y = Y
    U = 0.872021 Cb
    V = 1.229951 Cr
    

    To convert an RGB image to YUV, you can thus use

    RGB = imread('11111.bmp');  
    YCBCR = rgb2ycbcr(RGB);
    YUV(:,:,1) = YCBCR(:,:,1);               % Y  -> Y
    YUV(:,:,2) = 0.872021 * YCBCR(:,:,2);    % Cb -> U
    YUV(:,:,3) = 1.229951 * YCBCR(:,:,3);    % Cr -> V
    

    and to convert it back, use

    YCBCR1(:,:,1) = YUV(:,:,1);               % Y -> Y
    YCBCR1(:,:,2) = YUV(:,:,2) / 0.872021;    % U -> Cb
    YCBCR1(:,:,3) = YUV(:,:,3) / 1.229951;    % V -> Cr
    RGB1 = ycbcr2rgb(YCBCR1);   
    

    Note that if you are using uint8 as type for RGB, then YCBCR and YUV will be uint8 too and the conversion will be lossy. For a testimage of mine, the maximum difference between RGB and RGB1 was

    max(abs(RGB(:)-RGB1(:)))
    ans = 
         4
    

    To have a lossless conversion, you should use the double datatype. Note that MATLAB assumes that for uint8 images the values are between 0 and 255, while for double images, the values are between 0 and 1, so they would need to be scaled.