imwrite in matlab change the actual image data - matlab

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.

Related

generate an image from a vector, can't display the image

i have an image descriptor in a file.modQDH i need to display this image
this is my code
imagefiles = dir('*.modQDH');
nfiles = length(imagefiles); % Number of files found
fprintf('number est ');
fprintf('%d ',nfiles );
fprintf('%n');
A = importdata('obj1__0.modQDH');
disp(A);
when i use disp(a) the result is my vetcor
but me i need the image corresponding to this vector
i have used image(A) and imshow (A) but it doesn't works
disp shows the value of a variable, it does not create an image rendering
see
http://www.mathworks.com/help/matlab/ref/disp.html
try using imagesc which attempts to take care of some of the scaling issues

what is the right way to compute the measures for images with different color properties

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>

How to retrieve the luminance channel from an rgb image in MATLAB

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.

problems with imshow() and rgb2gray() in MATLAB

Good afternoon,
when running the following code:
testImage = double(imread(testfile));
figure; imshow(testImage)
greyTestImage = rgb2gray(testImage);
figure; imshow(greyTestImage)
I get unclear and mostly blank Images, I was unable to fx it using the colormap. The following is teh original image and the two resulting figures:
1:
2:
3:
You have to know the format of the image you are trying to read. To make this sure, I always use the following piece of code in my programs when I want to convert user defined image from unknown format to uint8 grayscale :
% load image
[filename, pathname] = uigetfile({'*.*'},'image file');
fullFilename = [pathname filename];
% Get image info, read it accordingly
info = imfinfo(fullFilename);
if(strcmp('truecolor',info.ColorType))
I = imread(fullFilename);
Igray = uint8(rgb2gray(I));
clear I
elseif(strcmp('grayscale',info.ColorType))
Igray = uint8(imread(fullFilename));
elseif(strcmp('indexed',info.ColorType))
[I,map] = imread(fullFilename);
Igray = uint8(ind2gray(I,map));
clear I map
else
error('statPart:FormatImage','Image format error');
end
clear info
Also, this : testImage = double(imread(testfile)); won't work if you assume testfile is uint8 and want to convert it to double (in double intensity shall range from 0 to 1). You have to do testImage = double(imread(testfile)) / 255;
Hope this help.
Cheers
Have you tried converting to 8 bit unsigned integers?
testImage = double(imread('PEYXW.jpg'));
figure; imshow(uint8(testImage))
greyTestImage = rgb2gray(uint8(testImage));
figure; imshow(greyTestImage)
This is probably an issue with the image you are loading.
The input to the rgb2gray function needs to be a 3-channel color image (MxNx3 matrix for the R,G,B channels).
If you use a built-in Matlab sample image, you can effectively do:
imdata = imread('ngc6543a.jpg');
figure; imshow(imdata)
Then:
test = rgb2gray(imdata);
Actually, Matlab provides the function Im2double instead of double to convert images to double precison:
testImage = im2double(imread(testfile));
figure; imshow(testImage)
greyTestImage = rgb2gray(testImage);
figure; imshow(greyTestImage)
In double precision, image RGB values are between 0 and 1, for uint8 they range between 0 and 127. When you use the double function, all RGB values keep their value, but they are in double precision. This means that any RBG tiple with values >= 1 will result in a double >= 1 and thus produce a white space in your image.
im2doubleactually scales the values to the range [0 1].

Why does XORing the red RGB image channel, saving, reloading and XORing again not give back the original image?

This is the code I use to change the red value
pic=imread('farooq1.jpg');
[imr,imc,clr]=size(pic);
for row=1:imr
for col=1:imc
for k=1:clr
if(k==1)
img2(row,col,k)=bitxor(pic(row,col,k),66);
else
img2(row,col,k)=pic(row,col,k);
end
end
end
end
imwrite(img2,'farooq_scr.jpg');
imshow(img2);
But when I use this same code again on the resulting file to undo XORing, the result does not match the original picture.
Please suggest me if you know a better way of doing this.
The reason you're unable to recover your original image has nothing to do with the code for processing the red color plane, which works correctly but can be done more efficiently and succinctly using the vectorized code suggested by Jonas:
img2 = pic;
img2(:,:,1) = bitxor(img2(:,:,1),66);
The problem you're having is actually a result of the format you're saving the image file in. By default, JPEG image files created using IMWRITE are saved using lossy compression to reduce the file size. This results in a loss of image information that makes it impossible to recover your original image when you load that image and reapply your processing.
You can fix your problem by specifying that lossless compression is used when saving your JPEG image, like so:
imwrite(img2,'farooq_scr.jpg','Mode','lossless');
EXAMPLE:
Here's an example using a JPEG image 'greens.jpg' that's included with the Image Processing Toolbox:
rawImg = imread('greens.jpg'); %# Load the original image
subplot(2,2,1);
imshow(rawImg); %# Display the original image
title('Original Image');
modImg = rawImg; %# Initialize a modified image
modImg(:,:,1) = bitxor(modImg(:,:,1),66); %# Modify the red plane of the image
subplot(2,2,2);
imshow(modImg); %# Display the modified image
title('Modified Image');
imwrite(modImg,'lossy_image.jpg'); %# Save with lossy compression
lossyImg = imread('lossy_image.jpg'); %# Reload the image
lossyImg(:,:,1) = bitxor(lossyImg(:,:,1),66); %# Reprocess the image
subplot(2,2,3);
imshow(lossyImg); %# Display the image
title({'Using Lossy Image' 'to Recover Original'});
imwrite(modImg,'lossless_image.jpg',... %# Save with lossless compression
'Mode','lossless');
losslessImg = imread('lossless_image.jpg'); %# Reload the image
losslessImg(:,:,1) = bitxor(losslessImg(:,:,1),66); %# Reprocess the image
subplot(2,2,4);
imshow(losslessImg); %# Display the image
title({'Using Lossless Image' 'to Recover Original'});
And here's the resulting set of images:
You can see that saving the image with lossless compression allows you to recover the original when you reapply your processing steps. You can confirm that you get back the exact same image as the original using the function ISEQUAL:
>> isequal(rawImg,lossyImg) %# Lossy image doesn't match; returns false
ans =
0
>> isequal(rawImg,losslessImg) %# Lossless image matches exactly; returns true
ans =
1
You have to make sure that the new image is of the same class as the old one. Also, you can get rid of a few loops
pic = imread('peppers.png');
%# initialize img2 to the same size and same class as pic
%# by making it a copy of pic
img2 = pic;
%# apply bitxor to the red channel
img2(:,:,1) = bitxor(pic(:,:,1),66);
%# write the data
imwrite(img2,'peppers_scr.png')
imshow(img2)
%# show that the reverse works
img3 = imread('peppers_scr.png');
img3(:,:,1) = bitxor(img3(:,:,1),66);
figure %# create new figure
imshow(img3)