Get specific label (incl. data) of k-means - matlab

first of all, I'd like to describe my issue with the kmeans in Matlab.
I select a point via mouse and use it for cluster initialization. This works fine.
After the segmentation of the data, I reshape the data back into proper style, because I need a matrix.
Now I want to select only the cluster of which the user selected the data via mouse.
Therefore I select the index of the mouse-coordinates to select the label, which I want to segmentate. Because of other extra data which is not connected or nearby the relevant data, but also gots the same label.
I want to select only connected-components in a neighbourhood of 8.
So here is my code snippet so far:
flatimg = double(reshape(croppedimg,size(croppedimg,1)*size(croppedimg,2),size(croppedimg,3)));
% kmeans
[idx, clusters] = kmeans(flatimg,2,'start',[seedpoint1(3);seedpoint2(3)]);
% form it back to a matrix
k=reshape(idx,size(croppedimg,1),size(croppedimg,2));
%convert point, which is part of the label I want to linear index
selectedobjectpoint = sub2ind(size(croppedimg),seedpoint1(2),seedpoint1(1));
hgplabel = k(selectedobjectpoint);
idx_object = find(k, hgplabel);
% also tried: idx_object = find(k == hgplabel);
I added a screenshot, which shows the direct output of kmeans:
So my aim is it here to get only the "white" OR the "black" ones.
Help or advice appreciated. If you've got any questions regarding the snippet or the goal, feel free to ask.
Thank you in advance!

I think the FIND command is throwing you off. You want something like:
logicalImage = k == hgplabel;
bwImg = bwlabel(logicalImage);
imagesc(bwImg)
FIND will output the indices where k == hgplabel. You want the matrix of zeros and ones where k takes that value (I think).
If you just want the connected components of that, the output of bwlabel will contain unique integers for each connected component, so imagesc(bwImg == 1) will show just component 1. And you can specify the connectivity

Related

How to calculate Gradient in matlab?

I am working on pedestrian step detection (acceleration). I want to calculate statistical features from my filtered signal. I have already calculated some and now I want to calculate gradient.
My data is of 1x37205 double. I calculated features using for loop with moving window size=2samples and 50% overlap of previous window. Below I am attaching the code I tried to calculate the gradient.
I am not sure if it is the right way to calculate or not? In addition, I am also unable to understand that what is the purpose to use gradient, how it can be useful for step detection and how to work with gradient? Could some one guide me or provide any code help in matlab?
%%Here M is mean and V is variance i already calculated from filtered data
G = zeros(length(window:length(M)), 2);
for i = window:length(M)
temp = gradient(M(i+1-window:i),V(i+1-window:i));
G(i, 1) = temp(2, 1); % "c1"
G(i, 2) = temp(2, 1); % "c2"
end
One of the best features of Matlab is its documentation. If you are unfamiliar on how to get specific function documentation, enter the following in the command line:
doc functionName
Alternatively, for 'brief' documentation that displays in the command line, you can enter:
help functionName
Also see the documentation link here.
Your question is worded poorly, so I will summarize what I understand and answer accordingly:
You have a step detection data (1*37205) double, let us call it stepSignal
stepSignal is position data
You want your window to be 2 steps with 50% overlap. This is the default behavior for the gradient function.
You do not need a "for" loop to achieve your goal. According to the documentation, "gradient" can take one input.
See the code below, and if need be add clarifications to the original question.
%% Assume that stepSignal is already imported into the workspace
velocity = gradient(stepSignal);
One last note, when you give "gradient" two inputs, it automatically assumes the second input is a uniform spacing value.

To find mean of image using .PixelValues in regionprops using matlab

I am trying to find out mean,kurtosis,skew etc of different connected regions seperately. May I found it using .PixelValue command using following code? or .PixelValue command to be used? Please help me.This is my first work.Please correct my code to find mean.
% Out is my region of interest output image.
[val num]=bwlabel(Out);
STATS=regionprops(val,'All');
for i=1:num
kk=STATS(i);
kk1=kk.PixelList;
% To find mean
[r c]=size(kk1);
ax(i)=r*c;
pp(i)=sum(sum(kk1));
bx(i)=pp(i)/su;
mean=bx(i);
end
If you want to compute the mean of the pixel values of a within connected components of Out, then you want to do as follows (assuming a is a grey-value image):
lab = bwlabel(Out);
stats = regionprops(lab,a,'PixelValues');
and then, for each stats.PixelValues, compute the mean:
m = zeros(size(stats))
for ii = 1:numel(stats);
m(ii) = mean(stats(ii).PixelValues);
end
or more simply:
m = cellfun(#mean,{stats.PixelValues})
Note that regionprops can be called with a second input image, which contains the grey values. The 'PixelValues' property is a list with pixel values for each connected component.
To further simplify the code, you can skip calling bwlabel, and directly pass the binary image to regionprops:
stats = regionprops(Out,a,'PixelValues');

Assigning arrays to a matrix in a function, syntax problems

I'm having trouble with the syntax in Matlab.
I'm trying to split an audio signal up into different segments (frames).
I would like to return the y-axis values to a matrix (each segment having its own column), and the corresponding time values with each segment having its own row.
I can't even get it to return just one single column and row pair (ie one frame). I just get returned two empty matrices. Here's my code.
function [mFrames, vTimeFrame] = Framing(vSignal,samplingRate,frameLPerc,frameshPerc)
totalTime=size(vSignal,1)/samplingRate
frameLength = totalTime*frameLPerc;
frameShift = totalTime*frameshPerc;
frameNumber =0;
check=frameLPerc;
while check<1
check = check+frameshPerc;
frameNumber=frameNumber+1;
end
start = 1;
% problem part
mFrames = vSignal(round((start:1/samplingRate:frameLength)*samplingRate));
vTimeFrame = round((start:1/samplingRate:frameLength)*samplingRate);
end
In the end I would like to be able to segment my entire signal into mFrames(i) and vTimeFrame(i) with a for-loop, but never mind that I cannot even get my function to return the first one (like I said empty matrix).
I know my segment code should be correct because I've got another script working with the same vSignal (it's a column vector by the way) that works just fine (y==vSignal):
voiced = y(round((1.245:1/Fs:1.608)*Fs));
plot(1.245:1/Fs:1.608,voiced)
I titled this with syntax problems because I'm very new to matlab and am used to Java. It feels very weird not initializing anything, and so I'm unsure whether my code is actually making any sense.
When testing I enter [m1,m2]=Framing(y,16000,0.1,0.05).
I got it.
start was not in the right domain. This is correct:
round((start/samplingRate:1/samplingRate:frameLength)*samplingRate)
When I plot(m2,m1) I now get the correct answer.
I do still have another question though, how can I assign these segments to my matrices?
for i=1:frameNumber
mFrames(:,i) = vSignal(round((start/samplingRate:1/samplingRate:frameLength)*samplingRate));
vTimeFrame(i) = round((start/samplingRate:1/samplingRate:frameLength)*samplingRate);
start=start+frameShift;
frameLength=frameLength+frameShift;
end
I get this error
In an assignment A(I) = B, the number of elements in B and I must be the same.
Like I said I'm trying to get the y-axis numbers in columns next to each other and the x-axis in rows.

MATLAB loading data from multiple .mat files

My data is x,y co-ordinates in multiple files
a=dir('*.mat')
b={a(:).name}
to load the filenames in a cell array
How do I use a loop to sequentially load one column of data from each file into consecutive rows of a new/separate array......?
I've been doing it individually using e.g.
Load(example1.mat)
A(:,1)=AB(:,1)
Load(example2.mat)
A(:,2)=AB(:,1)
Load(example3.mat)
A(:,3)=AB(:,1)
Obviously very primitive and time consuming!!
My Matlab skills are weak so any advice gratefully received
Cheers
Many thanks again, I'm still figuring out how to read the code but I used it like this;
a=dir('*.mat');
b={a(:).name};
test1=zeros(numel(b),1765);
for k=1:numel(b) S=load(b{k});
I then used the following code to create a PCA cluster plot
test1(k,:)=S.AB(:,2); end [wcoeff,score,latent,tsquared,explained] = pca(test1,... 'VariableWeights','variance');
c3 = wcoeff(:,1:3) coefforth = inv(diag(std(test1)))*wcoeff; I = c3'*c3 cscores = zscore(test1)*coefforth;
figure() plot(score(:,1),score(:,2),'+') xlabel('1st Principal Component') ylabel('2nd Principal Component') –
I was using 'gname' to label the points on the cluster plot but found that the point were simply labelled from 1 to the number of rows in the array.....I was going to ask you about this but I found out simply through trial and error if I used 'gname(b)' this labels the points with the .names listed in b.....
However the clusterplot starts to look very busy/messy once I have labelled quite a few points so now I am wondering is is possible to extract the filenames into a list by dragging round or selecting a few points, I think it is possible as I have read a few related topics.....but any tips/advice around gname or labelled/extracting labels from clusterplots would be greatly appreciated. Apologies again for my formatting I'm still getting used to this website!!!
Here is a way to do it. Hopefully I got what you wanted correctly :)
The code is commented but please ask any questions if something is unclear.
a=dir('*.mat');
b={a(:).name};
%// Initialize the output array. Here SomeNumber depends on the size of your data in AB.
A = zeros(numel(b),SomeNumber);
%// Loop through each 'example.mat' file
for k = 1:numel(b)
%// ===========
%// Here you could do either of the following:
1)
%// Create a name to load with sprintf. It does not require a or b.
NameToLoad = sprintf('example%i.mat',k);
%// Load the data
S = load(NameToLoad);
2)
%// Load directly from b:
S = load(b{k});
%// ===========
%// Now S is a structure containing every variable from the exampleX.mat file.
%// You can access the data using dot notation.
%// Store the data into rows of A
A(k,:) = S.AB(:,1);
end
Hope that is what you meant!

How to process individual connected components from 3D volume in matlab?

I have a 3D dataset containing multiple connected components. Using matlab, I would like to compute a certain metric for each of these components (the metric is not included in the 'regionprops' function). My question is what is the best way to do it?
The metric I would like to compute is the surface area. I know how to do this for one connected component, but I'm looking for an efficient way to do it for all components that meet a certain volume criteria.
What I have so far:
cc = bwconncomp(data,26); % find components
L = labelmatrix(cc); %
stats = regionprops(data, 'area');
for i = 1:length(cc.PixelIdxList)
if stats(i,1).Area > threshold
a = (L==i);
surfaceArea(i,1) = compute_surface_area(a);
end
end
I'm sure there is a better way to do this!
Thanks in advance, N
You may want to use arrayfun that computes the surface area for each connected component whose area is above threshold.
idx = find([stats.Area]>threshold);
arrayfun(#(ii) compute_surface_area(L == ii), idx, 'UniformOutput', 0 )
Here, the for loop is written in a single line of code.