Convert RGB image to YUV (MATLAB)
102 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
high speed
el 9 de Nov. de 2022
Comentada: high speed
el 10 de Nov. de 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 comentarios
Respuesta aceptada
Image Analyst
el 9 de Nov. de 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
Más respuestas (1)
DGM
el 9 de Nov. de 2022
Editada: DGM
el 9 de Nov. de 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 comentarios
Ver también
Categorías
Más información sobre Orange en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!