Convert RGB image to YUV (MATLAB)
97 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
high speed
il 9 Nov 2022
Commentato: high speed
il 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
im1=imread('peppers.png');
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 Commenti
Risposta accettata
Image Analyst
il 9 Nov 2022
I made some changes:
rgbImage = imread('peppers.png');
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
Più risposte (1)
DGM
il 9 Nov 2022
Modificato: DGM
il 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.
inpict = imread('peppers.png');
% 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)
% 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)
% compare built-in conversion
immse(rgbpict2,inpict)
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 Commenti
Vedere anche
Categorie
Scopri di più su Orange in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!