How do I create an array of image in matlab - matlab

I read one by one images from a directory and I wish to create an array of images with that to pass to my mexFunction that processes these images. What I am tried so far is not working. Let say I have 100 images 256x256 when I do
directory = uigetdir; fileList = dir(directory); imageVolume= [];
for idx = 3:numel(fileList)
tempImage = imread(fullfile(directory, fileList(idx).name));
imageVolume= [imageVolume tempImage];
end
Whenever I do that, I don't get an array of 256x256xn, instead I just get an image of 256x(256*n), which is not what I want. Any idea?

Use Cell Arrays. Assuming the rest of your code is right:
for idx = 3:numel(fileList)
tempImage{idx} = imread(fullfile(directory, fileList(idx).name));
end

Using cell arrays as #bjornsen suggested works. If you would rather not use cell arrays, you can use 3 dimensional matrices:
imageVolume(:,:,idx) = tempImage;
You must be sure, though, that all images are the same size. Otherwise, you're better off using cell arrays.

Related

Save Cell Array into 2D-Array in Matlab

I have a Cell Array 1*42 .
I want to save this cell array into 311029*42 array size in .mat file.enter image description here
How to do it ?
You can use cell2mat function to do this. You can see the mechanism of this function in this link (see the following image).
You can just horizontally concatenate a comma-separated list generated from the cell array, then save your new variable like so:
newData = [data{:}];
svae('your_file.mat', 'newData');
Let C be a cell array of 1x42 size. Then, run the following code to get the output array Y.
N = length(C);
L = size(C{1});
Y = size(L(1),L(2)*N);
for n = 1:N
Y(:,1+(n-1)*L(2):n*L(2)) = C{n};
end

How to use the PARFOR loop for image processing without loading all images together

I want to use a parfor loop for image processing. I do operations on single images and stacks of images. To keep the use of memory low I want to prevent storing all images in memory.
I start with the cell structure variable Imagepaths{}{} that contains
paths for different images in a cell in cell structure. function1 operates on all individual images and function2 operates on a stack of images, combining them into a single new image.
For example: Imagepaths{}{} contains 12 cell. Each cell contains a 1x5 cell with the paths of the images. function2 operates on such a 1x5 stack of images.
The following code i initially try to use but the variable Images{} gives an error for the PARFOR loop.
parfor l = 1:numel(Imagepaths)
for k = 1:numel(Imagepaths{l})
Image = imread(Imagepaths{l}{k});
Images{k} = function1(Image)
end
Image2{l} = function2(Images)
end
I came with a the following solution, but the disadvantage is that it takes a lot of memory as all images are stored.
parfor l = 1:numel(Imagepaths)
for k = 1:numel(Imagepaths{l})
Image = imread(Imagepaths{l}{k});
Images{l}{k} = function1(Image)
end
end
parfor l = 1:numel(Imagepaths)
Image2{l} = function2(Images{l})
end
Does somebody can mention a solution to preserve for storing all images.
In your original code, you've got two forms of indexing for Imagepaths inside the parfor loop, and that prevents slicing, which is what you want. See the doc for more on valid indexing forms for sliced variables. The easiest way to convince parfor that what you're doing is OK is to pull out a temporary array from Imagepaths using valid sliced indexing, and then operate on that.
The second problem I encountered is that your temporary array Images is used in a way that parfor thinks is order-dependent (which strictly speaking it could be, but I suspect in practice it is not). The simplest way to fix that is to assign a new empty cell array to Images on each iteration of the loop, like so:
parfor l = 1:numel(Imagepaths)
tmp = Imagepaths{l}; %# sliced indexing
Images = cell(1, numel(tmp)); %# force "Images" to be "temporary"
for k = 1:numel(tmp)
Image = imread(tmp{k});
Images{k} = function1(Image)
end
Image2{l} = function2(Images)
end
Based on the answer of Edric, mentioning temporary arrays, the following code also works without using the temporary variable "tmp" for the image paths.
parfor l = 1:numel(Imagepaths)
Images = cell(1, number(Imagepaths{l}));
for k = 1:numel(Imagepaths{l})
Image = imread(Imagepaths{l}{k});
Images{k} = function1(Image)
end
Image2{l} = function2(Images)
end

MATLAB reduce function?

I would like to add a cell array of images together using imadd, but imadd only takes two arguments. Is there a reduce function in MATLAB which I could use add all of these images together without writing a for loop?
images = {im1, im2, im3};
sum = reduce(#imadd, images);
You could just use an array with an extra dimension. E.g. for 2-d (grayscale images)
images = {im1, im2, im3};
imarr = cat(3, images{:});
imsum = sum(imarr, 3);
Of course there's no need to create the cell array in the first place; you could go straight to
imarr = cat(3, im1, im2, im3);
imsum = sum(imarr, 3);
or even
imsum = sum(cat(ndims(im1)+1, im1, im2, im3),ndims(im1)+1);
which also more generally combines any dimensional matrices.
Since you are using the Image Processing Toolbox, the IMLINCOMB function (linear combination of images) can also be used, just give all coefficients as one:
imsum = imlincomb(1,im1, 1,im2, 1,im3)

Matlab: Subscript + squeeze conveniently

I'm using matlab and am quite new to it. I'm used to Java and other langauges.
Some background: I'm manipulating images, I work with the imread, imshow etc. commands. I want to store multiple images in an array.
So what I do is
img_list = zeroes(num_images, 1200, 1600, 3) % height,width,RGB
and then I load the images with img_list(i,:,:,:) = my_image; iteratively. That is all working fine.
Now I can display the images as I want by doing imshow(squeeze(img_list(1,:,:,:))). I can't stand this. I would like something as simple as imshow(img_list(1)).
Any idea how I can do this?
I definetly am open to change the type of img_list. Any hints is appreciated. Maybe I could do something so all my images in img_list don't have to be of the same size?
Thanks in advance. :)
The easiest solution would be to use a cell array. Each element of a cell array is a container that can hold a variable of any type and size. You access the element of a cell array as array(i) (which returns a 1-by-1 cell). To access the contents of an element of a cell array, you use curly brackets, i.e array{i}. Also have a look at CELLFUN, which allows you to perform operations on each image.
%# initialize the cell array
img_list = cell(num_images);
%# add an image to the cell array
img_list{4} = someImage;
%# display the image
imshow(img_list{4})
%# display only the red channel
imshow(img_list{4}(:,:,3))
Using cell arrays, as Jonas suggested, is probably the Right Thing -- especially if you want to be able to have images of different sizes. But it's worth mentioning that you can make the simple 4-dimensional-array approach a little nicer: make the image number the last index instead of the first. Then you can say img_list(:,:,:,i) = my_image; and imshow(img_list(:,:,:,1)); with no need for squeezing. That's probably a little better for memory locality (hence for performance) too, though it won't be any better than using cell arrays.
Define a local anonymous function:
% Get image list from somewhere.
img_list = ...;
% ...
% Easy-access to individual frames.
nth_image = #(k) squeeze(img_list(k,:,:,:));
image_count = size(img_list,1);
% Loop over images.
% ...
This allows you to write the following list:
% Process each image.
for i = 1 : image_count,
img = nth_image(i);
% ...
end
If you have multiple image lists or this pattern occurs often, you can write more generic functions:
function [ img ] = get_nth_image ( img_list, k )
img = squeeze(img_list(k,:,:,:));
end
function [ img_list ] = set_nth_image ( img_list, img, k )
img_list(k,:,:,:) = img;
end

how to store heterogenous objects in matlab?

I need to make an image pyramid in matlab for one of my assignments. Though there are inbuilt methods to get the individual images in the pyramid, I am confused about how to store the handles to the images. (I don't have much experience with matlab)
Arrays don't work, since the images in the pyramid are of different size. I am looking for something like a list in .net, or arraylist in Java. In MATLAB linked list, they say that you can use the standard Java classes, but matlab hung when i tried to use java's arraylist. So, what is the best way to store a collection of heterogeneous data(or handles?) in matlab?
EDIT1 : The code which is not working:
im0 = imread('..\lenna-lg.jpg'); //im0 = 480*480*3 array
im1 = impyramid(im0,'reduce'); //im1 = 240*240*3 array
pyramid = [ im0, im1 ]; //Error : Error using ==> horzcat
//CAT arguments dimensions are not consistent.
So with some further searching, i have found out what is called a cell, which basically seems to be a heterogeneous array. (http://stackoverflow.com/questions/2662964/cell-and-array-in-matlab). So the following code is working now
im0 = imread('..\lenna-lg.jpg'); //im0 = 480*480*3 array
im1 = impyramid(im0,'reduce'); //im1 = 240*240*3 array
cell = [ {im0}, {im1} ]; //cell = 1*2 cell
ans = cell{1}; //ans = 480*480*3 array
This seems to be a very convenient way to handle heterogeneous data. Is this the right way to go about this?