Why do YCbCr channels saved as jpeg images,the pixels' values change? - matlab

I used the function rgb2ycbcr in matlab R2013a to change RGB to YCBCR color space. And I saved each channel of YCBCR as a jpeg image.Then I read the jpeg image,for example CB channel,but I found the pixel value is different in the jpeg image with the channel CB before saved. Why does this happen? Here is my code:
I = imread('pic.jpg'); % // 'pic.jpg' is an unin8 rgb image
YCBCR = rgb2ycbcr(I);
Y = YCBCR(:,:,1);
CB = YCBCR(:,:,2);
CR = YCBCR(:,:,3);
imwrite(Y,'F:\CASIA V1.0\Y.jpg','jpg');
imwrite(CB,'F:\CASIA V1.0\CB.jpg','jpg');
imwrite(CR,'F:\CASIA V1.0\CR.jpg','jpg');
Then I read the CB.jpg, I found the pixel value is different with those in YCBCR(:,:,2). Is anything wrong with my code? I will be very grateful if anybody can answer my question.

When you use imwrite to store an image as a jpg, it runs jpeg compression on the image before saving it to file. By default, the compression quality is set to 75% of the original. I'm guessing this is the reason behind some pixel values changing from the uncompressed images to the compressed ones.

Related

Convert grayscale uint8 image to RGB uint8 image

I have a code to run, which uses an original image and a mask image. The code assumes that the original image is RGB, but my original image is gray scale. This must be the result of the MATLAB whos command when I run the code:
Name Size Bytes Class Attributes
mask 308x206 63448 logical
origImg 308x206x3 190344 uint8
The mask is produced by making part of the image white and the rest is black (in a simple software like windows paint).
I want to use a gray-scale image as the origImg and produce the mask from the origImg in windows paint, but the result of the MATLAB whos command is as follows when I want to use custom photos with attributes as I said:
Name Size Bytes Class Attributes
mask 490x640x3 940800 uint8
origImg 490x640 313600 uint8
I have to convert the origImage dimension to x3 and remove the x3 from the mask, and also convert its class from unit8 to logical. In that case, I think that the code should work properly.
What should I do here in order to prepare the origImg and mask for that goal?
origImg=imread('G:\the_path\to\my_custom\image.png');
mask=imread('G:\the_path\to\my_custom\image_mask.png');
% I have to do something here to make it work.
whos;
% Rest of the code...
I am not sure if I understand you correctly.
To make a RGB image out of a gray-scale image, which still shows up as a gray-scale image, you can use
origImg = repmat(origImg,1,1,3);
which just repeats your gray-scale image for every channel of the RGB image.
For the mask, you have to do the opposite. since I don't know your image_mask.png file, I assume that it is a RGB image that uses only black and white. In this case, all three channels are the same and you could simply use one of them for the mask, doesn't matter which one:
mask = mask(:,:,1);
To convert it to logical, use
mask=logical(mask);

Grayscale image taking more space on disk than RGB when exported using MATLAB's 'imwrite' command

The size of the scaled grayscale image of size 256x256 is shown to be greater (65 kB) when saved using imwrite() than the original RGB image, which is of size 23 kB.
The extension of the file used is .bmp
img = imread('\path\input_image.bmp');
img=rgb2gray(img);
img=imresize(img,[256,256]);
imwrite(img, '\path\op_img.bmp', 'bmp');
Expected output: grayscale image occupies less space on the disc.
Actual output: grayscale image occupies more space than the same RGB image on the disc.
Matlab imwrite saves the .bmp image uncompressed.
If you save a 8bit grayscale image with 256x256 pixels as .bmp you'll end up with a file size of 256x256/1024kB = 64kB.
So there are two possible reasons for your input image to be smaller in size.
you increased the pixel count with the imresize operation
more pixels -> more data -> more memory
the input image was compressed
or any combination of both.

How to save DICOM image as JPEG without losing information

I have a dicom image that when I open it in MATLAB it is like this:
However when I see that via dicomviewer it is like this:
How can I save these dicom images without loosing their information in .jpeg format due to compression process?
I want to save the image so that I can retrieve the same information as I get from the respective dicom image.
Is it possible?
DICOM image data is typically stored as 16-bit unsigned integers, so you'll want to make sure that your image is stored within a uint16 matrix prior to saving so MATLAB knows to save it as such. Also, for some image formats, MATLAB requires that we explicitly state the bit depth.
% Save as a 16-bit Baseline JPEG with the highest quality
imwrite(uint16(data), 'image.jpg', 'Quality', 100, 'BitDepth', 16);
% Save as a 16-bit Lossless JPEG
imwrite(uint16(data), 'image.jpg', 'Mode', 'lossless', 'BitDepth', 16)
% Save as a 16-bit JPEG 2000 Image
imwrite(uint16(data), 'image.jp2', 'Mode', 'lossless')
If you don't need a JPEG for any particular reason, I would recommend a PNG (lossless).
% Save as 16-bit PNG
imwrite(uint16(data), 'image.png')
See the full list of available 16-bit formats here.
For visualization in MATLAB, you can specify the second input to imshow (or use imagesc) to automatically scale the displayed gray scale values to the data within the image
imshow(data, []) % or imagesc(data); axis image;

YCbCr to RGB conversion MATLAB using ycbr2rgb results in pink picture

I'm trying to convert an YCbCr image to RGB ysing MATLAB's function ycbcr2rgb. My resulting picture ends up being pink, and converting back again afterwards (should give me the original picture?) creates yet another image mostly grey.
For reference I tried to convert each channel individually by formula and it ends up the same.
I'm using a bigtiff format because of large filesize and if any help the imfinfo shows compression using JPEG.
Here is my code:
x=imread('picture.tiff','Index',9); %(9 subresolutions)
rgb=ycbcr2rgb(x);
imshow(rgb);
Can it be because of MATLABs function using the originial definition of YCbCr using ranges from 16-235 while my image is ranging from 0-255? If so is there any means of correcting this using the inbuild function?
I have added the pictures here, first image is showing imshow(rgb), while the second image is the original ycbcr. What I noticed is that in the Windows image viewer it actually shows it correct, it's just MATLAB's imshow that displays it pink after conversion.
Is there any chance you could point me in the right direction?
Thanks
Sonny
Apparently imread reads YCbCr images as RGB when loading it, which is why the problem occured.
Thanks for the help to all of you.
imread documentation
This link gives all the conversion formulae:
http://www.easyrgb.com/index.php?X=MATH&H=11
The below code converts image from RGB space to YCbCr space and back.
rgb = imread('board.tif');
imshow(rgb);
figure;
ycbcr = rgb2ycbcr(rgb);
imshow(ycbcr);
figure;
rgb2 = ycbcr2rgb(ycbcr);
imshow(rgb2);
Use MATLABs built in functions only. Also, if you're facing issues while converting from ycbcr to rgb you should probably try to convert the image to other form and then convert that form to RGB. (a dirty hack)
Just divide the image by 256 before converting it back to RGB.
y = ycbcr2rgb(z/256); % z holds the YCbCr image.
Worked for me.
Hope that helps :)

Why dicom image displayed are inverse colour and lossy for output. (Matlab)

Why are the colours inversed when I read a DICOM file? Also, when I am try to stretch and adjust the image output the export files are lossy (TIFF):
origImg = dicomread(uigetfile('~/matlab/*.*', 'Select Dicom File'));
J=imadjust(origImg,stretchlim(origImg),[0 1]);
CExpo = adapthisteq(J,'Distribution','exponential','Alpha',3);
imwrite(CExpo,'finish.tif','Resolution',100);
Resource and compare file: https://www.mediafire.com/?2xcwpt4khw3qh06
Matlab's Tiff class inverts uint8 image values when PhotometricInterpretation is 'Separated'. The Tiff specification specifically forbids this, but Matlab does it anyway for reasons unknown to me. That probably answers why your images are inverted. Generally speaking, Tiff images are not a lossy format, so if you believe there is a loss of fidelity, I do not understand how that is happening. (Nor do I know what a dicom image is).