how to store heterogenous objects in matlab? - 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?

Related

Directional Derivatives of a Matrix

I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.

Loopin through all the structures in a workspace [duplicate]

I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.

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)

How do I create an array of image in 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.

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