How to get value of Eccentricity from struct of Eccentricity in MATLAB? - matlab

I want to print Eccentricity of each connected component of my image and following is part of my code:
[B,L] = bwboundaries(bw,'noholes');
stats = regionprops(L,'Eccentricity');
for k = 1:length(stats)
stats(k);
end
But it doesn't really print any thing on output console. I want to get Eccentricity of each component on console.
And I want to store the float value of Eccentricity of each component in new one dimensional array so how do I do it ?

The ; in MATLAB suppresses the output of the executed line, and unlike most other languages is not required to terminate the end of a line. The easy way to "fix" this is to remove the ; from the for loop:
for k = 1:length(stats)
stats(k)
end
But it's a best practice to always have a ; at the end of every line. Rather than display this way, consider using disp() instead:
for k = 1:length(stats)
disp(stats(k));
end

Related

How do I adjust this code so that I can enter how many runs I want and it will store each run in a matrix?

I have created this code to generate a 1 set of lottery numbers, but I am trying to make it so that the user can enter how many sets they want (input n), and it will print out as one long matrix of size nX6? I was messing around with a few options from online suggestions, but to no avail. I put the initial for i=1:1:n at the beginning, but I do not know how to store each run into a growing matrix. Right now it still generates just 1 set.
function lottery(n)
for i=1:1:n
xlow=1;
xhigh=69;
m=5;
i=1;
while (i<=m)
lottonum(i)=floor(xlow+rand*(xhigh-xlow+1));
flag=0;
for j=1:i-1
if (lottonum(i)==lottonum(j))
flag=1;
end
end
if flag==0
i=i+1;
end
end
ylow=1;
yhigh=26;
m=1;
lottonum1=floor(ylow+rand*(yhigh-ylow+1));
z = horzcat(lottonum, lottonum1);
end
disp('The lotto numbers picked are')
fprintf('%g ',z)
disp (' ')
The problem is that you are not storing or displaying the newly generated numbers, only the last set. To solve this, initialize z with NaNs or zeros, and later index z to store each set in a row of z, by using z(i,:) = lottonum.
However, you are using i as iterator in the while loop already, so you should use another variable, e.g. k.
You can also set z as an output of the function, so you can use this matrix in some other part of a program.
function z = lottery(n)
% init z
z = NaN(n,6);
for k = 1:n
xlow=1;
xhigh=69;
m=5;
i=1;
while (i<=m)
lottonum(i)=floor(xlow+rand*(xhigh-xlow+1));
flag=0;
for j=1:i-1
if (lottonum(i)==lottonum(j))
flag=1;
end
end
if flag==0
i=i+1;
end
end
ylow=1;
yhigh=26;
lottonum1 = floor(ylow+rand*(yhigh-ylow+1));
z(k,:) = horzcat(lottonum, lottonum1); % put the numbers in a row of z
end
disp('The lotto numbers picked are')
disp(z) % prettier display than fprintf in this case.
disp (' ')
end
The nice answer from rinkert corrected your basic mistakes (like trying to modify your loop iterator i from within the loop => does not work), and answered your question on how to store all your results.
This left you with a working code, however, I'd like to propose to you a different way to look at it.
The porposed architecture is to divide the tasks into separate functions:
One function draw_numbers which can draw N numbers randomly (and does only that)
One function draw_lottery which call the previous function as many times as it needs (your n), collect the results and display them.
draw_lottery
This architecture has the benefit to greatly simplify your main function. It can now be as simple as:
function Draws = draw_lottery(n)
% define your draw parameters
xmin = 1 ; % minimum number drawn
xmax = 69 ; % maximum number drawn
nballs = 5 ; % number of number to draw
% pre allocate results
Draws = zeros( n , nballs) ;
for iDraw=1:1:n
% draw "nballs" numbers
thisDraw = draw_numbers(xmin,xmax,nballs) ;
% add them to the result matrix
Draws(iDraw,:) = thisDraw ;
end
disp('The lotto numbers picked are:')
disp (Draws)
disp (' ')
end
draw_numbers
Instead of using a intricated set of if conditions and several iterators (i/m/k) to branch the program flow, I made the function recursive. It means the function may have to call itself a number of time until a condition is satisfied. In our case the condition is to have a set of nballs unique numbers.
The function:
(1) draws N integer numbers randomly, using randi.
(2) remove duplicate numbers (if any). Using unique.
(3) count how many unique numbers are left Nu
(4a) if Nu = N => exit function
(4b) if Nu < N => Call itself again, sending the existing Nu numbers and asking to draw an additional N-Nu numbers to add to the collection. Then back to step (2).
in code, it looks like that:
function draw = draw_numbers(xmin,xmax,nballs,drawn_set)
% check if we received a partial set
if nargin == 4
% if yes, adjust the number of balls to draw
n2draw = nballs - numel(drawn_set) ;
else
% if not, make a full draw
drawn_set = [] ;
n2draw = nballs ;
end
% draw "nballs" numbers between "xmin" and "xmax"
% and concatenate these new numbers with the partial set
d = [drawn_set , randi([xmin xmax],1,n2draw)] ;
% Remove duplicate
drawn_set = unique(d) ;
% check if we have some more balls to draw
if numel(drawn_set) < nballs
% draw some more balls
draw = draw_numbers(xmin,xmax,nballs,drawn_set) ;
else
% we're good to go, assign output and exit funtion
draw = drawn_set ;
end
end
You can have both functions into the same file if you want.
I encourage you to look at the documentation of a couple of Matlab built-in functions used:
randi
unique

Plotting brownian motion matlab

First of all, I just want to say that I'm not that used to using matlab, but I need for an assignment, I'm supposed to create a "brownian movement". My code is currently looking like this:
clf
hold on
prompt = 'Ge ett input';
size = input(prompt) ;
numParticles = input('Ange antal partiklar');
axis([-size size -size size]);
Part = [];
color = 'brkgmyco';
for i = drange(1:numParticles)
Part = [Part [0;0]];
end
for i = drange(1:200)
dxdy = randn(2,numParticles);
k = Part
Part = Part + dxdy;
My concern is how to print, I would even want like a small delay on every print, so you really can see what's happening for the assignment, is this possible to achieve from the code I've written for now or should anything be changed? Thanks in advance!
Here are some basic problems with your code, regardless of what you are trying to do:
You use size as a variable name. Doing so overrides MATLAB's function size.
The function zeros creates an array initialized by zeros, no need for a loop for that.
Instead of calculating randn for 200 times in a loop, you can do it once, with dxdy = randn(2,numParticles,200) and then simply refer to dxdy(:,:,i) within the loop.
The same holds for summation. Instead of summing within a loop to get the cumulative sum, use cumsum like Part = cumsum(randn(2,numParticles,200),3); and then refer to Part(:,:,i), within the loop.
Now to your task. You said you want to know how to print, but I believe you want to plot because you use some commands like axis, clf and hold, that refer to graphic objects. However, you never really do plot anything.
The basic and general function for plotting in 2D is plot, but there are many other more specific functions. One of them is scatter, and it has a sister function gscatter, that takes triples of x, y and groupand plot each (x(k),y(k)) colored by their group(k).
This code plots the particles on an axes, and animate their movement:
prompt = 'Ge ett input';
scope = input(prompt) ;
numParticles = input('Ange antal partiklar');
N = 500;
Part = cumsum(randn(2,numParticles,N)*scope/100,3);
h = gscatter(Part(1,:,1),Part(2,:,1),1:numParticles);
axis([-scope scope -scope scope]);
legend off
for k = 2:N
for p = 1:numParticles
h(p).XData = Part(1,p,k);
h(p).YData = Part(2,p,k);
end
drawnow
end
Is this what you look for?

Saving a specific simulation time

I have a two-track model implemented in simulink. To control the velocity I use a PID-controller, so that the the output of the velocity looks like this:
now I want to implement a MATLAB function or simulink block that tracks the time when the velocity reaches a steady-state-behaviour and puts it into some kind of storage. I tried to implement something like this via the following MATLAB function with MATLAB-function-block:
function y = fcn(t,v,dv,tv)
%#codegen
if (v==tv+0.01) & (dv<0)
y=t
end
t is the clock-signal, v the velocity, dv the first derivation of the velocity and tv is the targetvelocity. The problem about this function is that there "y is not defined on some execution paths". do you have any ideas how to make this work?
I solved the problem without a MATLAB function using the simulink blocks data store memory and its read & write blocks. The signal that is coming in from bottom right side is the momentary velocity. The if statement is
(u1 >= 22.2) & (u1<=22.3) & (u2<0)
Since simulink is using time steps and the momentary velocity will never be exactly 22.2, you can not use u1==22.2
In SimuLink add a second output and a fifth input to your function. Then use that new output as a feedback to the function.
function [y, output] = fcn(t,v,dv,tv,input)
y = 0;
output = input;
if (v == tv + 0.01) && (dv < 0)
y = t;
if (input == -1)
output = t;
end
end
Attach the output to an IC block where you set the input initial value to -1 or whatever value you want to use. Then attach the IC block to the input of the function. output will be feedback constantly through the function. Once it's set it will reatin it's value forever.
function y = fcn(t,v,dv,tv)
%#codegen
y = zeros(length(t),1); % Initialise the array
for ii = 1:length(t)
if (v==tv+0.01) & (dv<0)
y(ii)=t;
else
y(ii)=0;
end
end
y(y==0)=[];
end
Two changes: added a semicolon after y=t to force it to not print it every time it is set. Second, your question, else y=[];, which means that y will be an empty matrix if you do not adhere to your if statement.
It now stores a 0 each time you do not adhere to the if statement. The line y(y==0)=[]; deletes all zeros, comment this line if you want your y to be the same length as the input variables.
function y = fcn(t,v,dv,tv)
%#codegen
y = zeros(length(t),1); % Initialise the array
ii=1;
while exist(t)
if (v==tv+0.01) & (dv<0)
y(ii)=t;
else
y(ii)=0;
end
ii = ii+1;
end
y(y==0)=[];
end

Can't understand the warning

My code works but every time it runs through line 13 it writes on the command window :"Warning: Integer operands are required for colon operator
when used as index ".
The relevant part of my code looks like that:
filename = uigetfile;
obj = mmreader(filename);
nFrames=obj.NumberOfFrames;
for k = 1 : nFrames
this_frame = read(obj, k);
thisfig = figure();
thisax = axes('Parent', thisfig);
image(this_frame, 'Parent', thisax);
if k==1
handle=imrect;
pos=handle.getPosition;
end
partOf=this_frame(pos(2):pos(2)+pos(4),pos(1):pos(1)+pos(3));%this is line 13
vector(k)=mean2(partOf);
title(thisax, sprintf('Frame #%d', k));
end
Why this warning appears and can i ignore it?
It's probably because one or more of the following: pos(2), pos(2)+pos(4), pos(1) and pos(1)+pos(3) are not integers, which indices are supposed to be. You may want to use the round function to round them up to integer values.
Maayan,
The problem seems to occur from the values of your pos vector (and the value of the calculations you make to pos vector values).
This is the solution quoted from MathWorks(MATLAB) website:
http://www.mathworks.com/support/solutions/en/data/1-FA9A2S/?solution=1-FA9A2S
Modify the index computations using the FIX, FLOOR, CEIL, or ROUND functions to ensure that the indices are integers. You can test if a variable contains an integer by comparing the variable to the output of the ROUND function operating on that variable when MATLAB is in debug mode on the line containing the variable.

MATLAB - Labeling Curves During Iteration

I want to show the p value that was used to generate each curve next to each of the curves plotted. Note that since there is a plot of E and -E, the same p value should be next to both. I've been attempting this for a while and I have not come across anything super useful.
t = -3.1;%coupling
a = 1;%distance between r1 and r3
n = 5;%latice vector span in a1 direction
m = 1;%latice vector span in a2 direction
i = -7;%unique axial vector t_hat direction
j = 11;%unique axial vector c_hat direction
max_p = abs((n*(i+j/2)-j*(m+n/2)));%# of unique p values
La = sqrt(3)*sqrt(m^2+n*m+n^2)*a/gcd(2*n+m,2*m+n);%unit cell length
C = sqrt(n^2+n*m+m^2);%circumference of the nanotube
hold on;
for p=0:1:max_p
kt = -pi/La:.05:pi/La;
kc = 2*pi*p/C;
ka1 = kc*a*.5*(2*n+m)/C + kt*a*sqrt(3)*.5*m/C;
ka2 = kc*a*.5*(n+2*m)/C - kt*a*sqrt(3)*.5*n/C;
E = abs(t+t*exp(1i*ka2)+t*exp(1i*ka1));
title_ = sprintf('(%d,%d) Carbon Nanotube Dispersion Diagram',n,m);
title(title_);
xlabel('k_{t}a');
ylabel('Energy (eV)');
plot(kt,E);
plot(kt,-E);
end
There is a command named text that writes comments into the figures,
http://www.mathworks.se/help/techdoc/ref/text.html
with if you can't solve it with that and the to string operation i misunderstood the question
First, do you need to plot both E and -E? Since these are the same except for their sign you don't really add any information to the plot by having -E there as well. However, if you do need both lines, then just construct an array of strings for the legend, during the loop, which has each string included twice (once for E and once for -E).
... Initial calculations ...
hold on;
for p=0:1:max_p
kt = -pi/La:.05:pi/La;
kc = 2*pi*p/C;
ka1 = kc*a*.5*(2*n+m)/C + kt*a*sqrt(3)*.5*m/C;
ka2 = kc*a*.5*(n+2*m)/C - kt*a*sqrt(3)*.5*n/C;
E = abs(t+t*exp(1i*ka2)+t*exp(1i*ka1));
plot(kt,E);
plot(kt,-E);
% Construct array containing legend text
legend_text{2*(p+1)-1} = strcat('p=', num2str(p));
legend_text{2*(p+1)} = strcat('p=', num2str(p));
end
title_ = sprintf('(%d,%d) Carbon Nanotube Dispersion Diagram',n,m);
title(title_);
xlabel('k_{t}a');
ylabel('Energy (eV)');
legend(legend_text)
I am sure there is a more elegant way of constructing the legend text, but the above code works. Also, notice that I moved the calls to xlabel, ylabel and title to outside of the loop. This way they are only called once and not for each iteration of the loop.
Finally, you need to take care to ensure that each iteration of the loop plots with a different line colour or line style (see edit below). You could colour/style each pair of E and -E lines the same for a given iteration of the loop and just display the legend for E (or -E), which would obviously halve the number of legend entries. To do this you will need to hide one of line's handle visibility - this prevents it from getting an item in the legend. To do this use the following in your loop:
plot(kt, E);
plot(kt,-E, 'HandleVisibility', 'off');
% Construct array containing legend text
legend_text{p+1} = strcat('p=', num2str(p));
Finally, it is best to include clear all at the top of your Matlab scripts.
Edit: To have each plotted line use a different colour for each iteration of your loop use something like the following
... initial calculations ...
cmap = hsv(max_p); % Create a max_p-by-3 set of colors from the HSV colormap
hold on;
for p = 0:1:max_p
plot(kt, E, 'Color', cmap(p,:)); % Plot each pair of lines with a different color
plot(kt, -E, 'Color', cmap(p,:));
end