I'm trying to retrieve the luminance component of a set of 'tif' images in matlab.
The code is bellow:
function [defaultImages] = readImgLum(nFiles)
% readImgLum reads a specified number of images in 'tif' format
% and retrieves the luminance component
narginchk(1, 1);
defaultImages = cell(nFiles, 1); % store all images in a vector
for i = 1 : nFiles
imagePreffix = int2str(i);
imageFullName = strcat(imagePreffix, '.tif');
image = imread(imageFullName);
imageYCbCr = rgb2ycbcr(image);
defaultImages{i} = squeeze(imageYCbCr(:,:,1));
end
Am I correctly extracting the luminance component?
As the comments have stated, there is no need for squeeze. This code also looks fine to me. However, if you want to skip computing all components of YCbCr just to extract the luminance, use the SMPTE / PAL standard for calculating luminance instead. This is actually done in rgb2gray in MATLAB if you want to look up the source.
In any case, assuming your images are unsigned 8-bit integer:
image = double(image);
defaultImages{i} = uint8(0.299*image(:,:,1) + 0.587*image(:,:,2) + 0.114*image(:,:,3));
BTW, image is a built-in command in MATLAB. It takes in any matrix, and visualizes it as an image in a new figure. I highly suggest you use another variable to store your temporary image as you may be calling further code later on that requires image as a function.
Related
This is a follow up to my previous post here
I'm using the following lines of code to convert the data type(from uint16 to uint8) of z-stack images in MATLAB
%Multiple image tiff conversion%
File_Name = "Test_Image.tiff";
Image_Data = imfinfo(File_Name);
Number_Of_Images = length(Image_Data);
Tiff_Structure = struct('Image_File',[]);
for Image_Index = 1: Number_Of_Images
Image = imread(File_Name,Image_Index);
Uint8_Image = im2uint8(Image);
%For more information and plotting individual images%
Tiff_Structure(Image_Index).Image_File = Uint8_Image;
%Saving the converted images to one tiff file%
imwrite(Uint8_Image,'Converted_Image.tiff','WriteMode','append');
end
In the documentation available here it is mentioned that
im2uint8(I) converts the grayscale, RGB, or binary image I to uint8,
rescaling or offsetting the data as necessary
I would like to know if it is possible to rescale the data before converting the datatype to uint8 and how this rescaling can be done.
Test_Image.Tiff
Suggestions will be really helpful.
EDIT:
Plotting the histogram of the image data gives the following
img_data = imfinfo(f);
n_img = length(img_data);
imgs = cell(1, numel(img_data));
for i = 1:numel(img_data)
imgs{i} = imread(f, i);
end
imgs = cat(3, imgs{:});
figure(1)
imhist(imgs(:), 256)
Assuming Image has values in the range 0-65535 (16bit)
to scale the values into an 8bit image:
first divided the image by 65535 (2^16) - this will normalize value range to 0-1
now you need to rescale to 8bit range of values, multiplying the image by 255
so basically:
scaled_image = uint8(double(Image)./65535*255)
Note: To preserve the dynamic range of the image it might be better to choose a different value to normalize with, e.g some max value across all stack
Below is the Matlab script to read and write (copy) an image using imwrite. I expect the newly written file to be same as the original file but the images and their histogram vary. The script is as under
%=====================================================================%
I = imread('lena.jpg');
I = imnoise(I,'salt & pepper',0.05);
I = im2double(I);
figure, imshow(I);
figure, imhist(I);
[M,N] = size(I);
J = I;
for i = 1 : M
for j = 1 : N
J(i,j) = I(i,j);
end
end
imwrite(J,'I1.png'); %tried with jpg and bmp, but same result
J = imread('I1.jpg');
figure, imhist(J);
%=====================================================================%
Kindly help to make me understand why these images vary
I tried running your code for Lena.jpg and Lena.png, for reading the input image and writing the output image.
When using .jpg, the histograms are different. This compression format is lossy, therefore it is expected that there is some loss of information. You must specify lossless when using imwrite if you want to prevent said loss.
imwrite(J,'I1.jpg','Mode','lossless');
When using .png, the histograms are the same as this compression format is lossless.
I am trying to implement rgb2lab() function in opencv.Here is my input and output image(the following links):
Is this comparable to the output of Matlab function rgb2lab().If not,please give the output obtained by rgb2lab function in Matlab for the input image.
You can convert an RGB image to Lab in Matlab as:
img = imread('path_to_image');
% Matlab 2015
%lab = rgb2lab(img);
% Matlab 2013
cform = makecform('srgb2lab');
lab = applycform(img,cform);
and in OpenCV as:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
Mat3b img = imread("path_to_image");
Mat3b lab;
cvtColor(img, lab, COLOR_BGR2Lab);
// NOTE: pixel values are the same as Matlab now.
// However, since OpenCV stores RGB values as BGR,
// to VISUALIZE the same image as Matlab you
// need to swap R and B channels.
// For visualization, whatever colorspace the image is in,
// the image is always considered as an BGR image.
Mat3b visuallySameAsMatlab;
cvtColor(lab, visuallySameAsMatlab, COLOR_BGR2RGB);
return 0;
}
NOTE: the pixel values are the same as Matlab after the call to cvtColor(img, lab, COLOR_BGR2Lab);. However, for visualization purposes, you need to swap B and R channels, as OpenCV internally stores BGR images as RGB.
When you visualize an image, in whatever color space, you are considering the pixel value as RGB (or BGR in OpenCV).
I need a little help guys in Matlab in Matrix Dimensions,
I Have two images imported by imread function:
im1 = imread('1.jpg');
im2 = imread('2.jpg');
im1 is the reference image, while im2 is the Noisy image.
In the workspace window, Matlab shows the im2 Dimensions like this: 768x1024x3
while im2 displayed as: 768x1024
They are both RGB, there's no greyscale images,
In fact the second image is the a compressed image (performed compression algorithm on it ) while the first image is natural JPEG Image, untouched
and for calculating MSE/PNSR for both images, the matrix dimensions must be the same.
I Will need to transform im1 dimensions to be 3d like the first image (768x1024)
I tried this functions (squeeze, reshape) and with no success
You were on the right track with repmat. Here's the correct syntax:
im2 = repmat(im2, [1 1 3]);
This says you want 1 replicate along the first dimension, 1 replicate along the second dimension, and 3 replicates along the third dimension.
Are you sure that both are RGB images because im2 has only one channel and it looks grayscale but it can also be a colormap image in that case try
[im2, map] = imread('im2.jpg');
and see if anything is appearing in map variable. If the image is indeed colormap image, the map variable should be of size 256 X 3.
What donda has suggested is repeating the grayscale channel 3 times to make it of size 768x1024x3. Another possibility is that noisy image was created by converting RGB image to grayscale or by taking green channel of RGB image. Verify the source of the image in that case.
About PSNR computation I have a feeling that there is some problem with your code. I have given my code below use this and see if it works. Get back to me if you face any problem.
function [Psnr_DB] = psnr(I,I_out)
I = double(I);
I_out = double(I_out);
total_error = 0;
for iterz = 1:size(I,3)
for iterx = 1:size(I,1)
for itery = 1:size(I,2)
total_error = total_error + (I(iterx,itery,iterz)-I_out(iterx,itery,iterz))^2;
end
end
end
MSE = total_error/numel(I);
Psnr = (255^2)/MSE;
Psnr_DB = 10*log10(Psnr) %#ok<NOPRT>
Lets say we have a simple RGB image on disk.
If we read the image using imread() it gets stored as uint8 type. Then I do Discrete Fourier Transform on it using fft(), the returned image is of double type.
Now, on storing this data as image on disk, using imwrite(), and again read using imread(), the precision of data seems to get lost and again the image is stored as uint8.
This means, I can't operate Inverse Discrete Fourier Transform on saved DFT image! How should I approach this one?
You need to use an file format that supports floating point images. Tiff is one of them. imwrite doesn't have the flexibility so you need to use the Tiff class. This will not work with complex data. If it's complex I would use matlabs mat format.
function imwriteDouble(filename,data)
% imwriteDouble(filename,data) saves floating point data in tiff image
n=ndims(data);
t=Tiff(filename,'w');
tagstruct.ImageLength = size(data,1);
tagstruct.ImageWidth = size(data,2);
tagstruct.BitsPerSample = 64;
if n==2
tagstruct.SamplesPerPixel = 1;
tagstruct.Photometric = Tiff.Photometric.MinIsBlack;
elseif n == 3
tagstruct.SamplesPerPixel = 3;
tagstruct.Photometric = Tiff.Photometric.RGB;
else
error('Image must have 2 or 3 dimensions');
end
tagstruct.Compression=Tiff.Compression.None;
tagstruct.SampleFormat=Tiff.SampleFormat.IEEEFP;
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
t.setTag(tagstruct);
t.write(data);
t.close();
end
You can read the image back using imread.