Updating a struct with new values in a for loop - arrays

My image array: C_filled = 256x256x3270
What I would like to do is calculate the centroids of each image, and store each centroid corresponding to each 'slice'/image into an array. However, when I try to update the array, like a regular array, I get this error:
"Undefined operator '+' for input arguments of type 'struct'."
I have the following code:
for i=1:3270;
cen(i) = regionprops(C_filled(:,:,i),'centroid');
centroids = cat(1, cen.Centroid);% convert the cen struct into a regular array.
cen(i+1) = cen(i) + 1; <- this is the problem line
end
How can I update the array to store each new centroid?
Thanks in advance.

That's because the output of regionprops (i.e. cen(i)) is a structure, to which you try to add the value 1. But since you try to add the value to the structure and not one of its field, it fails.
Assuming that each image can contain multiple objects (and therefore centroids), it would be best (I think) to store their coordinates into a cell array in which each cell can be of a different size, contrary to a numeric array. If you have the exact same number of objects in each image, then you could use a numeric array.
If we look at the "cell array" option with code:
%// Initialize cell array to store centroid coordinates (1st row) and their number (2nd row)
centroids_cell = cell(2,3270);
for i=1:3270;
%// No need to index cen...saves memory
cen = regionprops(C_filled(:,:,i),'centroid');
centroids_cell{1,i} = cat(1,cen.Centroid);
centroids_cell{2,i} = numel(cen.Centroid);
end
and that's it. You can access the centroid coordinates of any image using this notation:centroids_cell{some index}.

Related

Get specific cells from a cell array

I have a numeric array sized 1000x1 which have values 0 and 1, called conditionArray.
I have a cell array called netNames with the same size (1000x1) and its cells contain string values (which are name of some circuit nets).
I want to extract net names which from netNames which their pairwise condition bit is 1 in conditionArray.
E.g. if conditionArray(100) is equal to extract its net name from netNames{100}.
Output of this process can be stored in an string array or cell array.
Are there any ways to do this operation with pairwise operations or I should use a for statement for this?
You shall check out cellfun in Matlab anytime you want to manipulate each element inside a cellarray without using a for loop.
As I understand, you have:
N = 1000;
% an array with 0s and 1s (this generates random 0s and 1s):
conditionArray = randi([0,1],N);
% a cell array with strings (this generates random 5-character strings):
netNames = cell(N);
netNames = cellfun(#(c)char(randi([double('a'),double('z')],1,5)), netNames, 'UniformOutput',false);
To extract the elements from netNames where conditionArray is 1, you can do:
netNames(conditionArray==1)
This uses logical indexing into the cell array.

Targeting specific elements of cell arrays (Matlab)

I currently have a cell array consisting of 7x1 vectors. I need to extract the first element (1,1) of each vector from each cell and store these values in a new array. This is what I currently have:
for j = 1:numel(xvalues)
cellj = xvalues{j};
a = cellj(1:1);
avalues(1:j) = a;
end
However, I am just generating a cell array with the first element of the last cell, repeating.
How can I fix this?
You can also use cellfun to apply a function to each element in a cell array. So to extract the first element of each vector the following should work.
avalues = cellfun(#(x) x(1),xvalues);
Cellfun loops through each element in the cell array and passes it in to the anonymous function via #(x). We then process x by taking the first element x(1).
In cases such as yours, where the cell contents are matrices of the same size, and assuming your inputs are small enough (meaning that neither memory nor runtime are imminent issues) you can convert the cell array into a numeric matrix and select a vector along the relevant dimension:
function out = q48740494
%% Generate some data:
c = squeeze(num2cell(randi(20,7,1,20),[1,2]));
% c = 20×1 cell array of {7x1 double}
%% Convert this into a numeric array and output:
out = cell2mat(c.'); out = out(1,:);
% BONUS: another version of the line above.
% out = subsref(cell2mat(c.'), substruct('()', {1,1:numel(c)}) ) ;

Search elements of matrix in another cell in matlab

I have a column matrix and a cell array which has two columns.The first column has 1x2 doubles and the second column has 1x1 doubles.
For example
columnMatrix = [1;5];
cellArray = {[1,8],[10];[8,1],[20];[4,6],[80];[3,5],[40];[14,16],[85];[5,10],[36]};
I would like to search each element of columnMatrix in cellArray(:,1) and then return its corresponding value in cellArray(:,2)
For example the output has to be like this
newCell = {[1],[10,20];[5],[40,36]};
I tried using the ismember function in this way
[~,idx] = ismember(cell2mat(cellArray(:,1)),columnMatrix (: , 1));
This returns all the indices which have the searched element but they are in two seperate columns and I can not perform any other logical operation to get the corresponding second column entry.
Is there some way this operation can be achieved? Could some one please help?
Thanks
First of all, convert first column of cellArray to a matrix so it would be easier to search values in. Then iterate over columnMatrix values (e.g. using arrayfun, but you could also use for loop), find rows that match (any across columns) and select corresponding values from the second column of cellArray, converting to numeric array ([cellArray{...,2}]). Finally, append the columnMatrix as the first column of the resulting cell array:
columnMatrix = [1;5]; cellArray = {[1,8],[10];[8,1],[20];[4,6],[80];[3,5],[40];[14,16],[85];[5,10],[36]};
mat = cell2mat(cellArray(:,1));
values = arrayfun(#(x) [cellArray{any(mat==x,2),2}], columnMatrix, 'uni', false);
result = [num2cell(columnMatrix), values];

Store big structure in Matlab

I am fitting a statistical model in matlab using fitglm which returns a structure mdl. I would like to store many such structures in an array of cells to reuse them later but this seems not to work. Here is the code:
models = cell(size(quarterList,1)-lag-1,1);
for i=1:size(quarterList,1)-lag-1
%indicesTemp = find(and(annQuarters(:,2) <= quarterList(i+11,2),annQuarters(:,2) >= quarterList(i,2)));
memberTemp = ismember(annQuarters(:,:), quarterList(i:i+lag,:));
indicesTemp = find(memberTemp(:,2));
fprintf('Perdiod: Q%i %i to Q%i %i - Nb samples: %i \n',annQuarters(i,1),annQuarters(i,2),annQuarters(i+lag,1),annQuarters(i+lag,2),size(indicesTemp,1));
[Xtemp Ytemp] = categorizeVariables(X(indicesTemp,:),Y(indicesTemp,:));
mdl = fitglm(Xtemp,Ytemp-1,'Distribution','binomial', 'Link','logit');
models(i,1) = mdl;
end
Now when I try to assign such structure to a single cell, it works:
temp = cell(1,1);
mdl = fitglm(Xtemp,Ytemp-1,'Distribution','binomial', 'Link','logit');
temp = mdl;
Why is the assignment in the array of cells not working in that case? Any suggestion on how to go around this?
This doesn't work because using models(index) assignment (with ()) assumes that the thing on the right side is a cell. You instead want to use curly brackets which will copy the item on the right (of any type) into the cell array at the specified element.
models{i,1} = mdl;
If you really wanted to use (), you could instead convert the thing on the right to a cell first.
models(i,1) = {mdl};
The reason that your second example (with a scalar cell array) doesn't result in an error is because you aren't putting the output of fitglm into the cell array but rather overwriting the variable temp to point to mdl instead of the cell array.
temp = cell(1,1);
% Check if temp is a cell
iscell(temp)
%// TRUE
mdl = fitglm(Xtemp,Ytemp-1,'Distribution','binomial','Link','logit');
temp = mdl;
% Check if temp is still a cell (it isn't)
iscell(temp)
%// FALSE
All of that aside, you can actually store structs within an array themselves. You don't actually need a cell array unless the fields are different.
for i = 1:N
mdl(i) = fitglm(Xtemp, Ytemp - 1, 'Distribution', 'binomial', 'Link', 'logit');
end

Save unlimited matrix from cell arrays

I get a cell array which contains 103 cells of different dimensions. Each cell of my cell array represents a matrix and it can be displayed as an image. How can I extract each cell (ie each matrix) in a for loop?
I know how to do that one by one but not for the whole cell :
image1 = cellArray{1}; % extract matrix 1 (on 103) from the cell array #1
image2 = cellArray{2}; % and so on
Thanks for your help
The easiest way to loop through your cell array and apply to same function to every cell is to use cellfun. If your function returns a scalar e.g.
f = #(x)max(:)
then it's as simple as
cellfun(f, cellArray)
Note that f above is an anonymous function (or rather a function handle to an anonymous function), but more likely your function will be in its own m-file in which case you need to use the # operator:
cellfun(#f, cellArray)
Lastly, if your output is not a scalar then call
cellfun(#f, cellArray, 'uni' 0)

Resources