How to display Y, Cb and Cr components of an image?

92 visualizaciones (últimos 30 días)
Swapnil Srivastava
Swapnil Srivastava el 16 de Ag. de 2020
Editada: Image Analyst el 29 de Sept. de 2022
Hi everyone, I've got an image which im trying to seperate out its Y, Cb and Cr components and display them. I seperated them out using the equation that relates YCbCr to RGB.
%% Reading the image as a tiff format
im1=imread('image3.tiff');
im1=double(im1)/256;
im1(:,:,4)=[];
xsize=size(im1,1);
ysize=size(im1,2);
%% Transforming the image from RGB to YCbCr
R=im1(:,:,1);
G=im1(:,:,2);
B=im1(:,:,3);
Y=0.288*R+0.587*G+0.114*B;
Cb=-0.1687*R-0.3313*G+0.5*B;
Cr=0.5*R-0.4187*G-0.0813*B;
%% Display the various different Y, Cb and Cr
figure;
subplot(1,3,1)
image(im1);
I'm now trying to find out how do I display them seperately. Does anyone know how to do it?
Thank you

Respuesta aceptada

Stephan
Stephan el 16 de Ag. de 2020
Editada: Stephan el 16 de Ag. de 2020
I used the inbuild example file peppers_RGB_tiled.tif, which has no 4rd dimension that could be cleared, so i used a try catch block to avoid errors:
%% Reading the image as a tiff format
im=imread('peppers_RGB_tiled.tif');
im1=double(im)/256;
try
im1(:,:,4)=[];
catch
end
xsize=size(im1,1);
ysize=size(im1,2);
%% Transforming the image from RGB to YCbCr
R=im1(:,:,1);
G=im1(:,:,2);
B=im1(:,:,3);
Y=0.288*R+0.587*G+0.114*B;
Cb=-0.1687*R-0.3313*G+0.5*B;
Cr=0.5*R-0.4187*G-0.0813*B;
%% Display thoe original & the various different Y, Cb and Cr
figure;
hold on
subplot(1,4,1)
imshow(im);
subplot(1,4,2)
imshow(Y);
subplot(1,4,3)
imshow(Cb);
subplot(1,4,4)
imshow(Cr);
hold off
  2 comentarios
DGM
DGM el 2 de Mayo de 2022
Editada: DGM el 2 de Mayo de 2022
There are a couple problems with this answer.
First of all, the luma constants in the transform look like they got typo'd The BT601 luma constants are [0.299 0.587 0.114]. It should also be noted that while YCbCr and YPbPr use the same transformation matrix, common integer YCbCr has offsets and scaling to consider. For visual purposes, it should suffice, but don't expect the values to be directly comparable to the results from something like rgb2ycbcr().
Second, since the above transformation is essentially YPbPr, the chroma channels are unit-scale and centered on zero. Because of that, imshow() will truncate them. Instead, offset them by 0.5 for viewing.
im = imread('peppers.png');
im1 = im2double(im); % needs IPT in older versions
% Transforming the image from RGB to YCbCr
[R G B] = imsplit(im1); % R2018b+
Y = 0.299*R + 0.587*G + 0.114*B; % 0.299
Cb = -0.1687*R - 0.3313*G + 0.5*B;
Cr = 0.5*R - 0.4187*G - 0.0813*B;
% Display the original & the various different Y, Cb and Cr
subplot(2,2,1) % i changed the tiling for web-view
imshow(im);
subplot(2,2,2)
imshow(Y);
subplot(2,2,3)
imshow(Cb+0.5); % offset
subplot(2,2,4)
imshow(Cr+0.5); % offset

Iniciar sesión para comentar.

Más respuestas (2)

Image Analyst
Image Analyst el 16 de Ag. de 2020
Editada: Image Analyst el 29 de Sept. de 2022
Try this:
rgbImage=imread('peppers.png');
% Transforming the image from RGB to YCbCr
yCbCrImage = rgb2ycbcr(rgbImage);
[yImage, cbImage, crImage] = imsplit(yCbCrImage);
% If you have r2018a or earlier, use the code below instead of imsplit().
% yImage = yCbCrImage(:, :, 1);
% crImage = yCbCrImage(:, :, 2);
% cbImage = yCbCrImage(:, :, 3);
% Display thoe original & the various different Y, Cb and Cr
figure;
subplot(2, 2, 1)
imshow(rgbImage, []);
title('RGB Image', 'FontSize', 16);
subplot(2, 2, 2)
imshow(yImage, []);
title('Y Image', 'FontSize', 16);
subplot(2, 2, 3)
imshow(cbImage, []);
title('Cb Image', 'FontSize', 16);
subplot(2, 2, 4)
imshow(crImage, []);
title('Cr Image', 'FontSize', 16);
  6 comentarios
Manthan Anil Agrawal
Manthan Anil Agrawal el 28 de Sept. de 2022
Hello,
I am new to image processing not sure but is this correct ? looks like cr and cb got reversed.
[yImage, crImage, cbImage] = imsplit(yCbCrImage);
Shouldn't this be -
[yImage, cbImage, crImage] = imsplit(yCbCrImage);
Image Analyst
Image Analyst el 29 de Sept. de 2022
@Manthan Anil Agrawal, yes you are correct. Thanks for catching that and I'll fix it above.

Iniciar sesión para comentar.


DGM
DGM el 2 de Mayo de 2022
Editada: DGM el 2 de Mayo de 2022
While I agree with Image Analyst that grayscale representations of the chroma channels are accurate, easier to read, and should be more than sufficient, sometimes people want some sort of pseudocolor representations. This can either be done by colormapping or by representing the given chroma values on a locus of constant luma.
Consider the examples in the following related questions:
You should be able to take the concepts demonstrated in YIQ and LAB and apply them to YCbCr without much trouble.
RGB = imread('peppers.png');
YCC = rgb2ycbcr(RGB);
[Y Cb Cr] = imsplit(YCC);
z = 127*ones(size(YCC, 1), size(YCC, 2)); % chroma center is offset!
Ysub = 127*ones(size(YCC, 1), size(YCC, 2)); % assume some luma
% substitute new luma, zero opposite chroma channel
just_Cb = ycbcr2rgb(cat(3, Ysub, Cb, z));
just_Cr = ycbcr2rgb(cat(3, Ysub, z, Cr));
montage({RGB Y; just_Cb just_Cr}'); % display it
Like I said, I don't really think that's easy to intuit, and the fact that we're using a dummy luma value means it's a misrepresentation anyway. Take it as you will.
Maybe nobody will ever ask this, but I'll point it out anyway. While the grayscale representations of the luma and chroma channels can be taken and (if scaled properly) be concatenated and converted back into an RGB image, these pseudocolor representations generally cannot. Think about why that might be. Think about why it might seem like you could. After all, the pseudocolor versions of Cb and Cr just have some constant luma and are assembled using standard conversions. Why can't we just take one step backwards and get Cb and Cr and then convert back to RGB?
% try to reverse the process
YCC_Cb = rgb2ycbcr(just_Cb);
YCC_Cr = rgb2ycbcr(just_Cr);
Cbrec = YCC_Cb(:,:,2);
Crrec = YCC_Cr(:,:,3);
RGBrec = ycbcr2rgb(cat(3, Y, Cbrec, Crrec));
% show the error in the recovered image
err = im2double(imabsdiff(RGB,RGBrec));
imshow(err/range(err(:)));
Think about why it's saturated regions on the primary-secondary corners that are being distorted. What if we picked a different value for the substituted luma? Is there any luma value that would be safe?

Community Treasure Hunt

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

Start Hunting!

Translated by