Extract structure within cell structure

3 views (last 30 days)
Hello,
I need help extracting structures of difference sizes from an array. I want to to extract the structure into variables that go like this: stats1, stats2, stats3, stats4 and so on. I can do this line by line, but when I try to do this on a loop (because there will be 100 images) matlab won't run the code. I attached the images that I am working with
clear;
clc;
% Importing PNG images
for k = 1:3
a{k} = sprintf('AB%d.png', k);
AB{k} = imread(a{k});
%spliting to RGB channels and image filtering
[r{k},BW{k},b{k}] = imsplit(AB{k});
BW{k}= imsharpen(BW{k});
BW{k}=im2bw(BW{k},0.15);
%imshow(BW{k})
% getting images Stats
stats{k}= regionprops(BW{k},"all");
end
%Below is what I need help creating a loop. This works fine, but I'd like
%to have a loop rather than writting the same line over and over
stats1 = stats(1,1);
stats1 = cell2mat(stats1);
stats2 = stats(1,2);
stats2 = cell2mat(stats2);
stats3 = stats(1,3);
stats3 = cell2mat(stats3);
%And so on... This code works for my needs, but I need a loop to create a new variable from stats1 to stats 3
%(there will be more images, like 100)
I had this in mind, but it is also a cell with structures
for i=1
stats1(i)= stats1(1,i);
end
  2 Comments
Stephen23
Stephen23 on 3 Oct 2022
So far you have not given any reason why you need to force yourself into writing slow, complex, inefficient, buggy code which is hard to debug... when you already have a cell array (which you can trivially access using simple and efficient indexing):
"I had this in mind, but it is also a cell with structures"
Note that your loop does nothing.
Francisco
Francisco on 3 Oct 2022
Edited: Francisco on 3 Oct 2022
Thanks for answering.
The following code works for my needs, I am trying to locate spheroids from images of nerve tissue
%MATLAB CODE FOR REGIONPROPS
clear;
clc;
A = imread('AB10.png');
figure,imshow(A)
[r,BW,b] = imsplit(A);
figure,imshow(BW);
BW = imsharpen(BW);
%figure,imshow(BW)
%BW = imreducehaze(BW);
%BW = histeq(BW);
%BW = imnoise(BW);
BW = im2bw(BW,0.15);
figure,imshow(BW)
stats = regionprops(BW,"all");
n=1;
for i = 1:length(stats)
area(i)= stats(i).Area;
perimeter(i) = stats(i).Perimeter;
circularity(i)= stats(i).Circularity;
centroid{i}= stats(i).Centroid;
majoraxislength(i) = stats(i).MajorAxisLength;
minoraxislength(i) = stats(i).MinorAxisLength;
if circularity(i)~=Inf && circularity(i)>0.47 && area(i)>150
large_areas(n) = area(i);
large_perimeter(n) = perimeter(i);
large_circularity(n) = circularity(i);
large_centroid(n) = centroid(i);
large_majoraxislength(n) = majoraxislength(i);
large_minoraxislength(n) = minoraxislength(i);
n= n+1;
end
end
centers = large_centroid';
centers = cell2mat(centers);
large_minoraxislength = large_minoraxislength';
large_majoraxislength = large_majoraxislength';
large_Stats = table(large_areas',large_perimeter', large_centroid', large_circularity', large_majoraxislength, large_minoraxislength);
large_Stats.Properties.VariableNames(1:4) = {'Area' 'Perimeter' 'Centroid' 'Circularity'};
diameters = mean([large_majoraxislength large_minoraxislength],2);
radii = diameters/2;
hold on
viscircles(centers,radii);
hold off
This code is for only one image. What I am tyring to do, is for my code to process multiple images at once

Sign in to comment.

Accepted Answer

Kartikay Sapra
Kartikay Sapra on 6 Oct 2022
Edited: Kartikay Sapra on 6 Oct 2022
To achieve the given task, create a custom function (say 'analyse') which returns a struct (say 'out') and fields of 'out’ can be your desired 'stats'.
After completing the above stated workflow, create an empty cell array with size corresponding to number of images (say 'stats')
This workflow will look like:
n = 100; %assuming number of images is 100
stats = cell(n, 1);
for k = 1:n
stats{k} = analyse(k);
end
And your function may look like:
function out = analyse(k)
%MATLAB CODE FOR REGIONPROPS
filename = "AB" + k + ".png";
A = imread(filename);
figure,imshow(A)
[r,BW,b] = imsplit(A);
figure,imshow(BW);
BW = imsharpen(BW);
BW = im2bw(BW,0.15);
figure,imshow(BW)
stats = regionprops(BW,"all");
n=1;
for i = 1:length(stats)
out.area(i)= stats(i).Area;
out.perimeter(i) = stats(i).Perimeter;
out.circularity(i)= stats(i).Circularity;
out.centroid{i}= stats(i).Centroid;
out.majoraxislength(i) = stats(i).MajorAxisLength;
out.minoraxislength(i) = stats(i).MinorAxisLength;
if out.circularity(i)~=Inf && out.circularity(i)>0.47 && out.area(i)>150
out.large_areas(n) = out.area(i);
out.large_perimeter(n) = out.perimeter(i);
out.large_circularity(n) = out.circularity(i);
out.large_centroid(n) = out.centroid(i);
out.large_majoraxislength(n) = out.majoraxislength(i);
out.large_minoraxislength(n) = out.minoraxislength(i);
n= n+1;
end
end
out.centers = out.large_centroid';
out.centers = cell2mat(out.centers);
out.large_minoraxislength = out.large_minoraxislength';
out.large_majoraxislength = out.large_majoraxislength';
out.large_Stats = table(out.large_areas',out.large_perimeter', out.large_centroid', out.large_circularity', out.large_majoraxislength, out.large_minoraxislength);
out.large_Stats.Properties.VariableNames(1:4) = {'Area' 'Perimeter' 'Centroid' 'Circularity'};
out.diameters = mean([out.large_majoraxislength out.large_minoraxislength],2);
out.radii = out.diameters/2;
hold on
viscircles(out.centers,out.radii);
hold off
end
Now for each image ‘ABk.png’ you extract 'stats' as:
stats{k}
where k is the index of the image.
Furthermore, the fields can be viewed by using the fieldnames:
%example of 'area'
stats{k}.area
%and so on

More Answers (0)

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!