How can I find the size of an image? - image

I need the size of the image as a variable.
Here is what I tried:
a = dir('C:\example\Desktop\imagefolder\*.png');
numberofImages = length(a);
%sizeofimage?
matrix = zeros(numberofImages, sizeofimage);
How can I get the size of my image?

Maybe this will help. It will give you the size of each of the images in your folder.
a = dir('C:\example\Desktop\imagefolder\*.png');
numberofImages = length(a);
for i=1:numberofImages
img = imread(a(i).name);
sizeofImage{i} = size(img)
end
You can then access the sizes of the images using this notation:
sizeofImage{1}
Which will return something like this for an image 400x400:
ans =
400 400 3

You require an array of numbers to go into zeros, and size already provides you with one. Simply horzcat that (or use square brackets) with the number of images and you're done:
matrix = zeros([numberofImages, size(image)]);
Although I strongly suggest you to stop working on your project and start taking a class in MATLAB, read a book on it or take the MathWorks own tutorial, as this is about as basic as MATLAB gets. Since MATrix LABoratory is about matrices, size is important.

Related

rmagick color out of range

I am trying to average the colours in an image, I have come up with the following script (from here):
scrip.rb:
require 'rmagick'
file = "./img.jpg"
img = Magick::Image.read(file).first
color = img.scale(1, 1).pixel_color(0,0)
p [color.red, color.green, color.blue]
img.jpg:
BUT the RGB output is [31829, 30571, 27931].
Questions:
Shouldn't the numbers be in the range of [0-255]?
What am I doing wrong?
What you have there is the red, green, and blue histogram values.
You need to divide by 256 in order to get each RGB value. In this case, the RGB values are:
require 'rmagick'
file = "./img.jpg"
img = Magick::Image.read(file).first
color = img.scale(1, 1).pixel_color(0,0)
p [color.red/256, color.green/256, color.blue/256]
# => [124, 119, 109]
This blog post provides a more thorough explanation on how to analyse images with RMagick.
The reason for the odd output is due to the bit depth. As a previous answer states, "They are stored in a 'quantum depth' of 16-bits." This was an initial assumption, but by looking at previous answers, this makes more sense. In order to properly convert these numbers back to your typically desires [0-255] range, you must divide the values by 256.
Note: You can change the quantum depth during runtime. When reading the file, you should be able to use a block like shown in the following code.
img = Magick::Image.read(file){self.depth = 8}.first

Importing Stack of Images

So I have the code to import a stack of images, but I am getting an error: Subscripted assignment dimension mismatch.
myPath = 'E:\folder name\'; %'
fileNames = dir(fullfile(myPath, '*.tif'));
width = 1400;
height = 1050;
nbImages = length(fileNames);
C=uint8(zeros(width, height, nbImages));
for i=1:length(fileNames)
C(:,:,i)=imread(cat(2,'E:\folder name\',fileNames(i).name));
i
end
I understand that the error is originating from the for loop, but I don't know of any other way to fill in an empty matrix with images.
Your images must not be all the same size. You can handle this by using explicit assignment for the first two dimensions. This will zero-pad any images which are smaller than the rest.
im = imread(...);
C(1:size(im, 1), 1:size(im, 2), i) = im;
Also, there is a good chance that your images have multiple color channels (the third dimension), so you'll likely want to concatenate along the fourth dimension rather than the third.
C(:,:,:,i) = imread(...)
Obviously it all depends what you want to do with the images, but in general, if you want a "stack" of images (or a "stack" of anything, really), then it sounds like you should be collecting them as a cell array instead.
Also, the correct way to create safe filenames is using the fullfile command
e.g.
C = cell(1, length(nbImages));
for i = 1 : length (fileNames)
C{i} = imread (fullfile ('E:','folder name', fileNames(i).name));
end
If you really want to concatenate to a 3D matrix from your cell array, assuming you have checked this is possible, you can do this very easily using comma-separated-list generator syntax:
My3DMatrix = cat(3, C{:});

Filling Multiple Images in Matlab

I have the following code to import multiple images from one directory into a struct in Matlab, here is an example of the images.
myPath= 'E:\conduit_stl(smooth contour)\Collagen Contour Slices\'; %'
fileNames = dir(fullfile(myPath, '*.tif'));
C = cell(length(fileNames), 1);
for k = 1:length(fileNames)
filename = fileNames(k).name;
C{k} = imread(filename);
se = strel('disk', 2, 0);
C = imclose(C, se);
filled = imfill(C,'holes');
end
Though now I would like to perform a fill on all the images, later finding the centroids. However, when attempting this, an error stating: "Expected input number 1, I1 or BW1, to be one of these types: double, ... etc" I tried converting the images into double precision, though that just resulted in: "Conversion to double from cell is not possible."
This is most likely due to the structure type, the images are 'housed' in, but I have no idea concerning that.
Help on this would be greatly appreciated.
So to elaborate on my previous comments, here are a few things to change with your code:
C is not a structure but a cell array. The content of a cell array is access with {curly brackets}. If all your images are the same size, then it is more efficient to store them into a numeric array instead of a cell array. Since they seem to be logical images, your array would have 3 dimensions:
[height, width, numberofimages]
You could therefore start your code with:
myPath= 'E:\conduit_stl(smooth contour)\Collagen Contour Slices\'; %'
fileNames = dir(fullfile(myPath, '*.tif'));
%// if your images are of type uint8
C(height,width,length(fileNames)) = uint8(0);
C_filled = C; %// initialize new array to stored filled images
Also, since you are using the same structuring elements for your morphological operation on all the images, you can define it once outside the loop.
So your code could look like this:
se = strel('disk', 2, 0);
for k = 1:length(fileNames)
C(:,:,k) = imread(fileNames(k).name);
C_filled(:,:,k) = imfill(imclose(C(:,:,k), se),'holes');
end

How to transfer the .mat file to image file without any change?

I have a image.mat of about 4MB.
The size of some image file can also be 4MB.
Can the image.mat be transferred to image file?
I tried this, but that doesn't do the trick:
load image.mat %load Iw
imshow(mat2gray(Iw))
imwrite(Iw,'image.png');
IwNew = imread('image.png');
isequal(Iw,IwNew)
The result is 0; am I misunderstanding something?
The number in Iw are very important, so Iw can not be changed.
Actually my real problem is how to store float numbers into an image?
But MATLAB does not support Tiff 6.0, so I'll have to find some workaround.
I am doing a blind watermarking,and the decimal fraction of a number in Iw is important because it involve the information about another image.So the Iw can not be changed.
Actually,Mathematica can store floating floating-point data:
But my programs are all in MATLAB.
According to Matlab documentation:
"If A is a grayscale or RGB color image of data type double or single, then imwrite assumes that the dynamic range is [0,1] and automatically scales the data by 255 before writing it to the file as 8-bit values."
In other words: imwrite performs automatic conversion from double to uint8.
if you wish to keep the values of Iw unchanged, save it as a mat file and not as an image.
If you do want to save it as an image - there is going to be some loss of information. In this case, there are two things which need to be done:
Change the dynamic range of the matrix to [0,1]. (in your case, the range is between -0.0035 to 255.0035. Also, the matrix contain inf values).
If you want to get an equality, scale IwNew by 255, and convert it to uint8.
Code:
load image.mat %load Iw
%step 1, change the dynamic range of the image to [0,1].
%One way to do it is by using mat2gray on each channel separately.
Iw(:,:,1) = mat2gray(Iw(:,:,1));
Iw(:,:,2) = mat2gray(Iw(:,:,2));
Iw(:,:,3) = mat2gray(Iw(:,:,3));
%write the image to file
imwrite(Iw,'image.png');
%read the image
IwNew=imread('image.png');
%scale it, and convert to uint 8
Iw2 = uint8(Iw*255);
%check equality
isequal(Iw2,IwNew)
Result:
ans =
1
Alternatively, if you want to convert IwNew to double, perform the following:
%conversion to double
Iw2 = double(IwNew)/255;
Notice that in this case, the matrices won't be equal to one another,
Due to the loss of information which happened during the imwrite process (conversion from double to uint8).
Instead, they will be epsilon-close to one another, where epsilon = 0.0001.
In order to test this, write the following:
%equality check
sum(abs(Iw2(:)-Iw(:))>0.0001)
Result:
ans =
0
My MATLAB (R2010a) with the image processing toolbox is perfectly capable of storing double-valued pixel values, and retrieve them without loss of data.
Here's a shameless copy of this answer:
% Some random, data of type double
A = 7.6*rand(10);
% Construct TIFF image...
t = Tiff('test.tif', 'w');
% ...with these custom parameters...
tagstruct = struct(...
'ImageLength' , size(A,1),...
'ImageWidth' , size(A,2),...
'Compression' , Tiff.Compression.None,...
'SampleFormat' , Tiff.SampleFormat.IEEEFP,... % floating point
'Photometric' , Tiff.Photometric.MinIsBlack,...
'BitsPerSample' , 64,... % 8 bytes / double
'SamplesPerPixel' , 1,...
'PlanarConfiguration', Tiff.PlanarConfiguration.Chunky);
t.setTag(tagstruct);
% ...and write it to disk.
t.write(A);
t.close();
% Read the data actually written, and check if all
% information was indeed preserved:
B = imread('test.tif');
isequal(A,B)
Result:
ans =
1
Adjust in obvious ways if you have more than 1 channel (RGB).

How to make gif images from a set of images in matlab?

How to make '.gif' image from a set of '.jpg' images (say: I1.jpg, I2.jpg,..., I10.jpg) in matlab?
Ok here is a simple example. I got an image with a unicorn on it and remove 2 part to create 3 different images, just for the sake of creating an animated gif. Here is what it looks like:
clear
clc
%// Image source: http:\\giantbomb.com
A = rgb2gray(imread('Unicorn1.jpg'));
B = rgb2gray(imread('Unicorn2.jpg'));
C = rgb2gray(imread('Unicorn3.jpg'));
ImageCell = {A;B;C};
figure;
subplot(131)
imshow(A)
subplot(132)
imshow(B)
subplot(133)
imshow(C)
%// Just to show what the images look like (I removed spots to make sure there was an animation created):
%// Create file name.
FileName = 'UnicornAnimation.gif';
for k = 1:numel(ImageCell)
if k ==1
%// For 1st image, start the 'LoopCount'.
imwrite(ImageCell{k},FileName,'gif','LoopCount',Inf,'DelayTime',1);
else
imwrite(ImageCell{k},FileName,'gif','WriteMode','append','DelayTime',1);
end
end
As you see, its not that different from the example on the Mathworks website. Here my images are in a cell array but yours might be in a regular array or something else.That should work fine; when I open 'UnicornAnimation.gif' it is indeed a nice animation!
Hope that helps!

Resources