# Convert RGB image to YUV (MATLAB)

51 Ansichten (letzte 30 Tage)
high speed am 9 Nov. 2022
Kommentiert: high speed am 10 Nov. 2022
Dear,
I'm trying to convert an image from standard RGB to YUV and vice-versa And I need to plot each parameter Y, U, V in subplot. I tried with this program
plot_flag=1;
Im_YUV = rgb2yuv(im1,plot_flag);
[Y,U,V] = rgb2yuv(im1);
figure
imshow(Im_YUV)
figure
subplot(221), imshow(im1); title('RGB');
subplot(222), imshow(Y); title('Y'); colormap('YUV');
subplot(223), imshow(U); title('U'); colormap('YUV');
subplot(224), imshow(V); title('V'); colormap('YUV');
function YUV=rgb2yuv(RGB,plot_flag)
R = double(RGB(:,:,1));
G = double(RGB(:,:,2));
B = double(RGB(:,:,3));
%Conversion Formula
Y = 0.299 * R + 0.587 * G + 0.114 * B;
U = - 0.168736 * R - 0.331264 * G + 0.5 * B;
V = 0.5 * R - 0.418688 * G - 0.081312 * B;
if (plot_flag==1)
figure();
subplot(1,3,1);imshow(Y);title('Y');
subplot(1,3,2);imshow(U);title('U');
subplot(1,3,3);imshow(V);title('V');
end
YUV=cat(3,uint8(Y),uint8(U),uint8(V));
YUV=rgb2ycbcr(RGB);
end
but I got an error of too many output arguments in line of : [Y,U,V]=rgb2yuv(im1)
How can I fixe this error please !
##### 0 Kommentare-1 ältere Kommentare anzeigen-1 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

### Akzeptierte Antwort

Image Analyst am 9 Nov. 2022
plot_flag=0;
yuvImage = rgb2yuv(rgbImage,plot_flag);
[Y,U,V] = imsplit(yuvImage);
subplot(4, 2, 1:4);
imshow(yuvImage)
axis('on', 'image');
subplot(425), imshow(rgbImage); title('RGB');
cmap = gray(256);
subplot(426), imshow(Y, 'Colormap', cmap); title('Y');
subplot(427), imshow(U, 'Colormap', cmap); title('U');
subplot(428), imshow(V, 'Colormap', cmap); title('V');
function YUV=rgb2yuv(RGB,plot_flag)
R = double(RGB(:,:,1));
G = double(RGB(:,:,2));
B = double(RGB(:,:,3));
%Conversion Formula
Y = 0.299 * R + 0.587 * G + 0.114 * B;
U = - 0.168736 * R - 0.331264 * G + 0.5 * B;
V = 0.5 * R - 0.418688 * G - 0.081312 * B;
if (plot_flag==1)
figure();
subplot(1,3,1);imshow(Y, []);title('Y');
subplot(1,3,2);imshow(U, []);title('U');
subplot(1,3,3);imshow(V, []);title('V');
end
YUV=cat(3,uint8(Y),uint8(U),uint8(V));
YUV=rgb2ycbcr(RGB);
end ##### 1 KommentarKeine anzeigenKeine ausblenden
high speed am 10 Nov. 2022
@Image Analyst Thank you

Melden Sie sich an, um zu kommentieren.

### Weitere Antworten (1)

DGM am 9 Nov. 2022
Bearbeitet: DGM am 9 Nov. 2022
First, that's not YUV. I know everyone calls it YUV. If it's not analog PAL video, it's probably not YUV. That's the forward transform for YPbPr/YCbCr. If you think you still want YUV, there are conversion examples here.
Your outputs are obviously being replaced by the valid results from rgb2ycbcr(), so I don't know what you're trying to do or why. Maybe you were just testing things?
YUV=cat(3,uint8(Y),uint8(U),uint8(V)); % you assemble the output
YUV=rgb2ycbcr(RGB); % and then discard it
Either way, it appears you're trying to convert RGB to 8-bit integer YCbCr. You can't just multiply and be done. If you do that, you'll truncate half your chroma data and you won't have the expected margins.
After multiplication by the forward transform, Cb and Cr will (depending on the color content) span [-128 128] (note A(2,3) and A(3,1)). Converting that to uint8 will truncate all your color information. It needs to be offset.
Margins might be a variable thing, but I'm going to assume that they're expected by whatever will read the data. Certainly, rgb2ycbcr() and ycbcr2rgb() expect standard margins. The synopsis mentions this:
YCBCR is uint8 where Y is in the range [16 235], and Cb and Cr are in the range [16 240].
Here's an example of manual conversion. You're free to adapt it to your needs.
% transformation matrix
A = [0.299 0.587 0.114;-0.1687 -0.3313 0.5;0.5 -0.4187 -0.08131];
Asc = [219; 224; 224]; % channel scaling for uint8
os = [16; 128; 128]; % offset
% convert to 8-bit YCbCr, compare to built-in tools
s = size(inpict);
yccpict = uint8(reshape(reshape(im2double(inpict),[],3)*(A.*Asc).' + os.',s));
yccpict2 = rgb2ycbcr(inpict);
% compare
immse(yccpict,yccpict2)
ans = 5.5271e-04
% convert back to 8-bit RGB, compare to built-in tools
rgbpict = im2uint8(reshape((reshape(double(yccpict),[],3) - os.')/(A.*Asc).',s));
rgbpict2 = ycbcr2rgb(yccpict2);
% compare manual conversion
immse(rgbpict,inpict)
ans = 0.3881
% compare built-in conversion
immse(rgbpict2,inpict)
ans = 0.3884
The small difference is merely a matter of order of operations.
As a sidenote. I mentioned A(2,3) and A(3,1). Those two terms determine the half-width of the chroma plane in each direction. Since they're neatly half, the chroma data is a nice intmax-width and can be offset by 128 to fit back into [0 255]. Look at those terms in the YUV forward transformation matrix. If you tried to do the same with YUV, V would be [-157 157]. Offsetting won't fit that back into [0 255].
##### 0 Kommentare-1 ältere Kommentare anzeigen-1 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

### Kategorien

Find more on Image Processing and Computer Vision in Help Center and File Exchange

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!