Saved image is different when read in matlab - image

I created an matrix using some calculation.I saved it in the BMP format.But when I am reading it back in MATLAB,the content of it changes totally.Only where value is 0 is correct.All other pixels are having values 255.Why is this.How to solve this??
It is showing image correctly when imsec command is used
for i=1:length(pixel_matrix)
pixel=char(pixel_matrix(i));
r=7;
pixel_value=0;
for j=1:4
s=r-1;
if(pixel(j)=='A')
temp_bin=0;
elseif(pixel(j)=='B')
temp_bin=(2^r)+(2^s);
elseif(pixel(j)=='C')
temp_bin=(2^s);
elseif(pixel(j)=='D')
temp_bin=(2^r);
end
pixel_value=pixel_value+temp_bin;
r=r-2;
end
pixel_row(i)=pixel_value;
end
i=1;
j=1;
for m=1:length(pixel_row)
pixel_value(i,j)=pixel_row(m);
j=j+1;
if(j==65)
i=i+1;
j=1;
end
end
for i=1:64
for j=1:64
picture(i,j)=uint8(pixel_value(i,j));
end
end
imwrite(picture,'C:\Users\XXX\Desktop\pic.bmp');
aaaa=imread('C:\Users\XXX\Desktop\pic.bmp');

the problem is most likely that you are filling picture with uint8 values, but when not specified otherwise, images in MatLab are doubles between 0 and 1. Try using the Map option for imwrite or norm the values of pixel_value(i,j) to fit them between 0 and 1 like this:
%...
for i=1:64
for j=1:64
picture(i,j)=pixel_value(i,j)/255; %<- Norm things here...
end
end

Related

How to save 3d arrays in Matlab that are generated in a loop?

I'm reading in 3d arrays, subtracting all of them from one of them, and trying to save the results as the same type of arrays. They are all equal sizes to each other, 1888x3520x6.
Here is the piece of code that I have:
[FileName,PathName,FilterIndex] = uigetfile('*.x3d*','MultiSelect','on');
numfiles = size(FileName,2);
FileName{1}
entirefile1 =fullfile(PathName,FileName{1})
Im1 = x3dread(entirefile1);
for j = 2:numfiles
FileName{j}
entirefile2 =fullfile(PathName,FileName{j})
Im2 = x3dread(entirefile2);
J = num2str(j);
strcat('ImDelta', J);
ImDelta = imsubtract(Im1, Im2);
end
I see that I'm creating a character sring by using strcat. But I'm not making it into a new file name. Only one file is resulting at the end of the loop.
(x3dread function is similar to "load" for working with images, only it is specifically written to handle the type of the 3dimention files that I have.)
Any help is appreciated. I'm just a beginner.

Matlab image filtering without using conv2

I've been given a task to create image filtering function for 3x3 matrices, and its outcome must be equal to conv2's. I have written this function, but it filters image incorrectly:
function [ image ] = Func134( img,matrix )
image=img;
len=length(img)
for i=2:1:len-1
for j=2:1:len-1
value=0;
for g=-1:1:1
for l=-1:1:1
value=value+img(i+g,j+l)*matrix(g+2,l+2);
end
end
image(i,j)=value;
end
end
i=1:1:length
image(i,1)=image(i,2)
image(i,len)=image(i,len-1)
image(1,i)=image(2,i)
image(len,i)=image(len-1,i)
end
Filtration matrix is [3,10,3;0,0,0;-3,-10,-3]
Please help to figure out what is wrong with my code.
Some sample results I get between conv2 and my code are seen below.
First off, this line doesn't make sense:
i=1:1:length;
I think you meant to use len instead of length as the ending index:
i=1:1:len;
Now referring to your code, it is correct, but what you are doing is correlation not convolution. In 2D convolution, you have to perform a 180 degree rotation of the kernel / mask and then do the weighted sum. As such, if you want to achieve the same results using conv2, you must pre-rotate the mask before calling it.
mask = [3,10,3;0,0,0;-3,-10,-3]
mask_flip = mask(end:-1:1,end:-1:1);
out = conv2(img, mask, 'same');
mask_flip contains the 180 degree rotated kernel. We use the 'same' flag to ensure that the output size of the result is the same size as the input. However, when using conv2, we are assuming that the borders of the image are zero-padded. Your code simply copies the border pixels of the original image into the resulting image. This is known as replicating behaviour but that is not what conv2 does natively. conv2 assumes that the border pixels are zero-padded as I mentioned before, so what I would suggest you do is create two additional images, one being the output image that has 2 more rows and 2 more columns and another being the input image that is the same size as the output image but you place the input image inside this matrix. Next, perform the filtering on this new image, place the resulting filtered pixels in the output image then crop this result. I've decided to create a new padded input image in order to keep most of your code intact.
I would also recommend that you abolish the use of length here. Use size instead to determine the image dimensions. Something like this will work:
function [ image ] = Func134( img,matrix )
[rows,cols] = size(img); %// Change
%// New - Create a padded matrix that is the same class as the input
new_img = zeros(rows+2,cols+2);
new_img = cast(new_img, class(img));
%// New - Place original image in padded result
new_img(2:end-1,2:end-1) = img;
%// Also create new output image the same size as the padded result
image = zeros(size(new_img));
image = cast(image, class(img));
for i=2:1:rows+1 %// Change
for j=2:1:cols+1 %// Change
value=0;
for g=-1:1:1
for l=-1:1:1
value=value+new_img(i+g,j+l)*matrix(g+2,l+2); %// Change
end
end
image(i,j)=value;
end
end
%// Change
%// Crop the image and remove the extra border pixels
image = image(2:end-1,2:end-1);
end
To compare, I've generated this random matrix:
>> rng(123);
>> A = rand(10,10)
A =
0.6965 0.3432 0.6344 0.0921 0.6240 0.1206 0.6693 0.0957 0.3188 0.7050
0.2861 0.7290 0.8494 0.4337 0.1156 0.8263 0.5859 0.8853 0.6920 0.9954
0.2269 0.4386 0.7245 0.4309 0.3173 0.6031 0.6249 0.6272 0.5544 0.3559
0.5513 0.0597 0.6110 0.4937 0.4148 0.5451 0.6747 0.7234 0.3890 0.7625
0.7195 0.3980 0.7224 0.4258 0.8663 0.3428 0.8423 0.0161 0.9251 0.5932
0.4231 0.7380 0.3230 0.3123 0.2505 0.3041 0.0832 0.5944 0.8417 0.6917
0.9808 0.1825 0.3618 0.4264 0.4830 0.4170 0.7637 0.5568 0.3574 0.1511
0.6848 0.1755 0.2283 0.8934 0.9856 0.6813 0.2437 0.1590 0.0436 0.3989
0.4809 0.5316 0.2937 0.9442 0.5195 0.8755 0.1942 0.1531 0.3048 0.2409
0.3921 0.5318 0.6310 0.5018 0.6129 0.5104 0.5725 0.6955 0.3982 0.3435
Now running with what we talked about above:
mask = [3,10,3;0,0,0;-3,-10,-3];
mask_flip = mask(end:-1:1,end:-1:1);
B = Func134(A,mask);
C = conv2(A, mask_flip,'same');
We get the following for your function and the output of conv2:
>> B
B =
-5.0485 -10.6972 -11.9826 -7.2322 -4.9363 -10.3681 -10.9944 -12.6870 -12.5618 -12.0295
4.4100 0.1847 -2.2030 -2.7377 0.6031 -3.7711 -2.5978 -5.8890 -2.9036 2.7836
-0.6436 6.6134 4.2122 -0.7822 -2.3282 1.6488 0.4420 2.2619 4.2144 3.2372
-4.8046 -1.0665 0.1568 -1.5907 -4.6943 0.3036 0.4399 4.3466 -2.5859 -3.4849
-0.7529 -5.5344 1.3900 3.1715 2.9108 4.6771 7.0247 1.7062 -3.9277 -0.6497
-1.9663 2.4536 4.2516 2.2266 3.6084 0.6432 -1.0581 -3.4674 5.3815 6.1237
-0.9296 5.1244 0.8912 -7.7325 -10.2260 -6.4585 -1.4298 6.2675 10.1657 5.3225
3.9511 -1.7869 -1.9199 -5.0832 -3.2932 -2.9853 5.5304 5.9034 1.4683 -0.7394
1.8580 -3.8938 -3.9216 3.8254 5.4139 1.8404 -4.3850 -7.4159 -4.9894 -0.5096
6.4040 7.6395 7.3643 11.8812 10.6537 10.8957 5.0278 3.0277 4.2295 3.3229
>> C
C =
-5.0485 -10.6972 -11.9826 -7.2322 -4.9363 -10.3681 -10.9944 -12.6870 -12.5618 -12.0295
4.4100 0.1847 -2.2030 -2.7377 0.6031 -3.7711 -2.5978 -5.8890 -2.9036 2.7836
-0.6436 6.6134 4.2122 -0.7822 -2.3282 1.6488 0.4420 2.2619 4.2144 3.2372
-4.8046 -1.0665 0.1568 -1.5907 -4.6943 0.3036 0.4399 4.3466 -2.5859 -3.4849
-0.7529 -5.5344 1.3900 3.1715 2.9108 4.6771 7.0247 1.7062 -3.9277 -0.6497
-1.9663 2.4536 4.2516 2.2266 3.6084 0.6432 -1.0581 -3.4674 5.3815 6.1237
-0.9296 5.1244 0.8912 -7.7325 -10.2260 -6.4585 -1.4298 6.2675 10.1657 5.3225
3.9511 -1.7869 -1.9199 -5.0832 -3.2932 -2.9853 5.5304 5.9034 1.4683 -0.7394
1.8580 -3.8938 -3.9216 3.8254 5.4139 1.8404 -4.3850 -7.4159 -4.9894 -0.5096
6.4040 7.6395 7.3643 11.8812 10.6537 10.8957 5.0278 3.0277 4.2295 3.3229

Creating Image stacks and writing GDF file

I am attempting to write a function that stack up series of images into image stack and converting it into a gdf file. I don't really know much about GDF files, so please help me out.
X=[];
for i=1:10
if numel(num2str(i))==1
X{i}=imread(strcat('0000',num2str(i),'.tif'));
elseif numel(num2str(i))==2
X{i}=imread(strcat('000',num2str(i),'.tif'));
end
end
myImage=cat(3,X{1:10});
s=write_gdf('stack.gdf',myImage);
Above is to read my images labeled 00001 to 00010, all in grayscale. Everything is fine except in the last line
s=write_gdf('stack.gdf',myImage);
as when I run it, I receive an error:
Data type uint8 not supported
Any help on what this means? Should I convert it to some other colour format?
Thank you in advance!
I would write the code rather like this (I do not have write_gdf function so I can not properly test the code):
NumberOfFiles = 10;
X={}; % preallocate CELL array
for n=1:NumberOfFiles % do not use "i" as your varable because it is imaginary unit in MatLab
FileName = sprintf('%05d.tif',n);
img = imread(FileName); % load image
X{i} = double(img); % and convert to desired format
end
myImage = cat(3,X{1:NumberOfFiles});
s = write_gdf('stack.gdf',myImage);
Keep in mind that
double(img); % and convert to desired format
will not change data range. Your image even in double format will have data range from 0 to 255 if it was in uint8 format on disk. If you need to normalize your data to 0..1 range you should do
X{i} = double(img)/255;
or in more unversal form
X{i} = double(img) / intmax(class(img));

MatLab (Image Processing, Image Acquisition) How to save captured images by webcam without overwriting the original file name?

I want to save images without overwriting them whenever I hit the pushbutton. Can you please help me how save images without overwriting the original? What I want to do is whenever I'll hit the pushbutton, It will generated 1 image at a time without deleting the original.
Just like in digital cameras, whenever I will hit the trigger button, it will save 1 image and the file name will be image1.jpg. So basically, if I will push trigger again, it will capture 1 image again and the file name will be image2.jpg and so on.
here is my code:
counter = 1; %initialize filename increment
vid = videoinput('winvideo',2);
set(vid, 'ReturnedColorSpace', 'RGB');
img = getsnapshot(vid);
imshow(img);
savename = strcat('C:\Users\Sony Vaio\Documents\Task\images\image_' ,num2str(counter), '.jpg'); %this is where and what your image will be saved
imwrite(img, savename);
counter = counter +1; %counter should increment each time you push the button
My code saves and keeps on overwriting the filename image1.jpg.
To make things clear
1 push to the pushbutton, 1 image saves.
it's like it will call the whole block code every hit at pushbutton.
I hope you guys can help me. I really troubled right now :(
Thank you :)
If this is the code that makes up the callback function for that pushbutton, then yes indeed, it will execute the entire block every time you push it.
If that is the case, you'll need to change it to this:
%// initialize filename increment
persistent counter;
if isempty(counter)
counter = 1; end
vid = videoinput('winvideo', 2);
set(vid, 'ReturnedColorSpace', 'RGB');
img = getsnapshot(vid);
imshow(img);
%// this is where and what your image will be saved
savename = [...
'C:\Users\Sony Vaio\Documents\Task\images\image_', ...
num2str(counter), '.jpg'];
imwrite(img, savename);
%// counter should increment each time you push the button
counter = counter + 1;
or, you could check what files are actually present, and use the next logical filename in the sequence:
vid = videoinput('winvideo', 2);
set(vid, 'ReturnedColorSpace', 'RGB');
img = getsnapshot(vid);
imshow(img);
%// this is where and what your image will be saved
counter = 1;
baseDir = 'C:\Users\Sony Vaio\Documents\Task\images\';
baseName = 'image_';
newName = [baseDir baseName num2str(counter) '.jpg'];
while exist(newName,'file')
counter = counter + 1;
newName = [baseDir baseName num2str(counter) '.jpg'];
end
imwrite(img, newName);
Every time you push that button the counter value resets to 1 because of the very first statement:
counter = 1
and hence the error.
counter = length(dir('*.jpg')) + 1; %Counts the number of .jpg files in the directory
That should do the job.
Zaher:
I'm online program about image processing and image acquisition from the camera in writing MATLAB.
When receiving the image every few seconds I get a picture of the camera.
Photos must be stored and processed in statistical process control charts.
When the first image after image acquisition program hangs and stops.
Please code to get images every 10 seconds online from cameras send images that can be used in statistical process control.
Thank

What is the fastest way to load multiple image tiff file in matlab?

I have a multiple image tiff file (3000 frames for example) and want to load the each image into matlab (I am using 2010a now). But I found it takes longer time to read images as the index of the frame increasing. The following is the code I am using now
for i=1:no_frame;
IM=imread('movie.tif',i);
IM=double(IM);
Movie{i}=IM;
end
Is there any other way to do it faster?
The TIFF-specific syntax list for IMREAD says the following for the 'Info' parameter:
When reading images from a multi-image
TIFF file, passing the output of
imfinfo as the value of the 'Info'
argument helps imread locate the
images in the file more quickly.
Combined with the preallocation of the cell array suggested by Jonas, this should speed things up for you:
fileName = 'movie.tif';
tiffInfo = imfinfo(fileName); %# Get the TIFF file information
no_frame = numel(tiffInfo); %# Get the number of images in the file
Movie = cell(no_frame,1); %# Preallocate the cell array
for iFrame = 1:no_frame
Movie{iFrame} = double(imread(fileName,'Index',iFrame,'Info',tiffInfo));
end
You may want to preassign the array Movie (or use R2011a, where growing an array inside a loop is less of an issue)
Movie = cell(no_frame,1);
for i=1:no_frame;
IM=imread('movie.tif',i);
IM=double(IM);
Movie{i}=IM;
end
I had the same problem and found this using that I tried this code. I get different time than he did but it is still much better than other image formats. For the last method to work you should find tifflib.mexa64 in your matlab directory and copy it into your working directory.
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
t=zeros(1,1000);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
for i=1:NumberImages
tic
FinalImage(:,:,:,i)=imread(FileTif,'Index',i);
t(i)=toc;
end
%disp(sprintf('test1 timing result:\n\t\t%d',toc));
mean(t)
clear
%%
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
t=zeros(1,1000);
for i=1:NumberImages
tic
FinalImage(:,:,:,i)=imread(FileTif,'Index',i,'Info',InfoImage);
t(i) = toc;
end
%disp(sprintf('test2 timing result:\n\t\t%d',toc));
mean(t)
clear
%%
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
t=zeros(1,1000);
TifLink = Tiff(FileTif, 'r');
for i=1:NumberImages
tic
TifLink.setDirectory(i);
FinalImage(:,:,:,i)=TifLink.read();
t(i) = toc;
end
TifLink.close();
%disp(sprintf('test3 timing result:\n\t\t%d',toc));
mean(t)
clear
%%
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
FileID = tifflib('open',FileTif,'r');
rps = tifflib('getField',FileID,Tiff.TagID.RowsPerStrip);
t=zeros(1,1000);
for i=1:NumberImages
tic
tifflib('setDirectory',FileID,i);
% Go through each strip of data.
rps = min(rps,nImage);
for r = 1:rps:nImage
row_inds = r:min(mImage,r+rps-1);
stripNum = tifflib('computeStrip',FileID,r);
FinalImage(row_inds,:,:,i) = tifflib('readEncodedStrip',FileID,stripNum);
end
t(i)=toc;
end
mean(t)
tifflib('close',FileID);
I have written a Matlab class to efficiently and quickly read TIFF stacks.
Load multi-page TIFF stacks into Matlab fast.
or from the file exchange:
Fast lazy-loading of TIFF stacks.
I have found that it is much faster to avoid using imread. Try this:
function data = FastTiff(filename)
warning('off','all') % Suppress all the tiff warnings
tstack = Tiff(filename);
[I,J] = size(tstack.read());
K = length(imfinfo(filename));
data = zeros(I,J,K);
data(:,:,1) = tstack.read();
for n = 2:K
tstack.nextDirectory()
data(:,:,n) = tstack.read();
end
warning('on','all')
end

Resources