Convert RGB image to YUV (MATLAB)

조회 수: 79 (최근 30일)
high speed
high speed 2022년 11월 9일
댓글: high speed 2022년 11월 10일
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 !

채택된 답변

Image Analyst
Image Analyst 2022년 11월 9일
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

추가 답변 (1개)

DGM
DGM 2022년 11월 9일
편집: DGM 2022년 11월 9일
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)
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].

카테고리

Help CenterFile Exchange에서 Convert Image Type에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by