How to revert signed distance function back to binary image? - matlab

So I used MATLAB's bwdist function to obtain the distance transform of a binary image. My question is, how do I transform a signed distance matrix back into a binary image?
D = bwdist(BW)
Specifically, is there a transform that can go back from BW -> D?

If D = bwdist(BW), how about BW0 = D<=0?
Consider the first example from the bwdist documentation:
bw = zeros(5,5); bw(2,2) = 1; bw(4,4) = 1
bw =
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
[D,IDX] = bwdist(bw)
D =
1.4142 1.0000 1.4142 2.2361 3.1623
1.0000 0 1.0000 2.0000 2.2361
1.4142 1.0000 1.4142 1.0000 1.4142
2.2361 2.0000 1.0000 0 1.0000
3.1623 2.2361 1.4142 1.0000 1.4142
To get back your binary image, you just want the points in the distance transform that are equal to zero (i.e. on a non-zero pixel in the original bw):
>> bw0 = D<=0
bw0 =
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
>> isequal(bw,bw0)
ans =
1

Related

Donoho-Tanner Phase Transition Matlab

I'm trying to create phase-transition plots in Matlab, but don't know how to program the acutal plots. My data is, for example, the following matrix:
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0.1000 1.0000
0 0 0 0 0 0 0 0 0 0 0.2000 1.0000
0 0 0 0 0 0 0 0 0 0.2000 0.3000 1.0000
0 0 0 0 0 0 0 0 0 0.1000 0.5000 1.0000
0 0 0 0.1000 0 0.4000 0.3000 0.5000 0.7000 1.0000 0.9000 1.0000
0.6000 0.4000 0.8000 0.9000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000
For now, what I want to do is basically plot the rows against the columns and represent the entries as shades, for example with 1 being represented as white and 0 being represented as black. The result should look somehting like this:
Thanks in advance!
use imagesc
colormap(gray)
imagesc(my_data,[0 1])
0 maps to black and 1 maps to white

How to reorder the rows and columns of a matrix multiplying a vector indexed by (i,j)

I am trying to construct a particular matrix A which multiplies a column vector v= [p_0,0; p_0,1; ... p_0,N; p_1,0; ...; p_N,N].
I know the required matrix (B say) if the vector v was rearranged in the order given by sorting by the second index before the first ( i.e if v were [p_0,0; p_1,0; ... p_N,0; p_0,1; ...; p_N,N]), however would like to rearrange the rows and columns of this matrix to obtain A so that it multiplies the correctly ordered v.
Example:
B =
-2.6667 1.0000 0 0 0 0 0 0 0
-0.5000 0 0.5000 0 0 0 0 0 0
0 -1.0000 -0.4706 0 0 0 0 0 0
0 0 0 -2.6667 1.0000 0 0 0 0
0 0 0 -0.5000 0 0.5000 0 0 0
0 0 0 0 -1.0000 -0.4706 0 0 0
0 0 0 0 0 0 -2.6667 1.0000 0
0 0 0 0 0 0 -0.5000 0 0.5000
0 0 0 0 0 0 0 -1.0000 -0.4706
multiplying v in the wrong order
p_0,0
p_1,0
p_2,0
p_0,1
p_1,1
p_2,1
p_0,2
p_1,2
p_2,2
As long as I understood, you want to convert matrix B to the matrix A in the following order:
v1= [p_0,0; p_0,1; ... p_0,N; p_1,0; ...; p_N,N]
v2=[p_0,0; p_1,0; ... p_N,0; p_0,1; ...; p_N,N]
where A*v1 equals to B*v2.
For this, you need swapping of each row of the matrix.
Try this code:
m=length(B); % m is equal to NxN
N=sqrt(m);
A=zeros(m,m);
for i=0:N-1
for j=0:N-1
A(j+i*N+1,:)=B(i+N*j+1,:);
end
end

Matlab : What am I doing wrong? (Indexing)

I'm trying to solve a system of 10 linear equations out of which the middle 8 equations look alike. They look like this :
t_i-1 - 2.3086*(t_i) + t_i+1 == -7.7160
where i = 2:9
so I decided to construct the coefficient matrix and the constant matrix(array) for the system of equations through looping.This is what I did.
T = sym('t' , [1 10]); %% Creates a vector T = [ t1 t2 .... t10]
A_10 = zeros(10,10);
b_10 = zeros(10,1);
for i = 2:9 %% This loop generates the equations and arranges them in the matrices A_10 and B_10.
T(i-1) - 2.3086*T(i) + T(i+1) == -7.7160;
[A_10(i,i-1:i+1),b_10(i,1)] = equationsToMatrix(ans)
end
Everything except for the ninth row(last but one) is correct in the Matrix A_10. This is what A_10 looks like
A_10 =
Columns 1 through 9
0 0 0 0 0 0 0 0 0
1.0000 -2.3086 1.0000 0 0 0 0 0 0
0 1.0000 -2.3086 1.0000 0 0 0 0 0
0 0 1.0000 -2.3086 1.0000 0 0 0 0
0 0 0 1.0000 -2.3086 1.0000 0 0 0
0 0 0 0 1.0000 -2.3086 1.0000 0 0
0 0 0 0 0 1.0000 -2.3086 1.0000 0
0 0 0 0 0 0 1.0000 -2.3086 1.0000
0 0 0 0 0 0 0 1.0000 1.0000
0 0 0 0 0 0 0 0 0
Column 10
0
0
0
0
0
0
0
0
-2.3086
0
The last three elements of the row nine should be 1 , -2.3086 , 1 like the previous rows but it shows 1, 1, -2.3086. What am I doing wrong here?
This is what the iteration looks like in the loop
ans = t8 - (11543*t9)/5000 + t10 == -1929/250
The equation is correct too. I can't figure out what the problem is.
Without the second input vars, equationsToMatrix uses symvar to determine the variable list.
Using symvar directly with the last equation gives
>> i = 9;symvar(T(i-1) - 2.3086*T(i) + T(i+1) == -7.7160)
ans =
[ t10, t8, t9]
So for whatever reason, symvar produced the incorrect ordering for only the last equation (possibly because 1 < 9). To remedy the situation, pass your intended ordering using the second input
eqn = T(i-1) - 2.3086*T(i) + T(i+1) == -7.7160;
[A_10(i,i-1:i+1),b_10(i,1)] = equationsToMatrix(eqn,T(i-1:i+1));
You'll also noticed I assigned the equation to an explicit variable eqn. This is better practice than relying on ans.
Also, since you're producing a numeric array anyway, you can produce A without the Symbolic Toolbox in a number of ways. For example:
n = 10;
A = full(spdiags(ones(n,1)*[1,-2.3086,1],[-1,0,1],n,n));
A([1,end],:) = 0;

for loops and matrices in matlab

I am trying to link two equations, where I use a for loop calculate the value of k from the range of frequencies (eg. 1-5 Hz) then use each of the k values and substitute the values of k into a 6x6 matrix. Can anyone help show me how to create a matrix for each value of k in Matlab?
1st Equation
for f = 1:5; % Range of Frequencies (Hz)
f;
w = 2.*pi.*f; % Angular Frequency (Hz)
p = 8050;% Density of Mild Steel(kg/m^3)
v = 0.30; % Poissons Ratio of Mild Steel
R = 0.02; % Radius of Pipe (m)
E = 210*10^9; % Youngs Modulus of Mild Steel (pa)
a = (w.^2).*p;
b = (p.*(1-(v.^2)).*(R.^2).*(w.^2)-E);
c = (p.*(R.^2).*(w.^2)-E).*E;
**k(f) = sqrt((a.*b)/c); % k = Wave Number**
end
2nd Equation (6x6 Matrix)
k =
L1=0.1;
L2=0.6;
L3=0.6;
D= [0,0,exp(-k*L1),exp(-k*L2),0,0; exp(-k*L1),1,exp(-k*L1),exp(-k*L2),0,0; -k*exp(-k*L1),k,k*exp(-k*L1),-k*exp(-k*L2),0,0;0,0,exp(-k*(L1+L2)),k,-exp(-k*(L1+L2)),-exp(-k*L3);0,0,-k*exp(-k*(L1+L2)),1,k*exp(-k*(L1+L2)),k*exp(-k*L3);0,0,exp(-k*(L1+L2)),1,0,0]
(Answer modified following the comment)
You can try definig the output array D as a 3 dimensions array.
D=NaN(6,6,length(k))
for i=1:length(k)
D(:,:,i)= [0,0,exp(-k(i)*L1),exp(-k(i)*L2),0,0; exp(-k(i)*L1),1,exp(-k(i)*L1),exp(-k(i)*L2),0,0; -k(i)*exp(-k(i)*L1),k(i),k(i)*exp(-k(i)*L1),-k(i)*exp(-k(i)*L2),0,0;0,0,exp(-k(i)*(L1+L2)),k(i),-exp(-k(i)*(L1+L2)),-exp(-k(i)*L3);0,0,-k(i)*exp(-k(i)*(L1+L2)),1,k(i)*exp(-k(i)*(L1+L2)),k(i)*exp(-k(i)*L3);0,0,exp(-k(i)*(L1+L2)),1,0,0]
end
The D array will be:
D(:,:,1) =
0 0 0.9999 0.9993 0 0
0.9999 1.0000 0.9999 0.9993 0 0
-0.0012 0.0012 0.0012 -0.0012 0 0
0 0 0.9991 0.0012 -0.9991 -0.9993
0 0 -0.0012 1.0000 0.0012 0.0012
0 0 0.9991 1.0000 0 0
D(:,:,2) =
0 0 0.9998 0.9985 0 0
0.9998 1.0000 0.9998 0.9985 0 0
-0.0025 0.0025 0.0025 -0.0025 0 0
0 0 0.9983 0.0025 -0.9983 -0.9985
0 0 -0.0025 1.0000 0.0025 0.0025
0 0 0.9983 1.0000 0 0
D(:,:,3) =
0 0 0.9996 0.9978 0 0
0.9996 1.0000 0.9996 0.9978 0 0
-0.0037 0.0037 0.0037 -0.0037 0 0
0 0 0.9974 0.0037 -0.9974 -0.9978
0 0 -0.0037 1.0000 0.0037 0.0037
0 0 0.9974 1.0000 0 0
D(:,:,4) =
0 0 0.9995 0.9971 0 0
0.9995 1.0000 0.9995 0.9971 0 0
-0.0049 0.0049 0.0049 -0.0049 0 0
0 0 0.9966 0.0049 -0.9966 -0.9971
0 0 -0.0049 1.0000 0.0049 0.0049
0 0 0.9966 1.0000 0 0
D(:,:,5) =
0 0 0.9994 0.9963 0 0
0.9994 1.0000 0.9994 0.9963 0 0
-0.0061 0.0062 0.0061 -0.0061 0 0
0 0 0.9957 0.0062 -0.9957 -0.9963
0 0 -0.0061 1.0000 0.0061 0.0061
0 0 0.9957 1.0000 0 0
Hope this helps.
I will try to answer your question...
Firstly, you don't need the initial for loop. You can calculate all values of wavelength without loops.
f = 1:5; % Range of Frequencies (Hz)
w = 2.*pi.*f; % Angular Frequency (Hz)
p = 8050;% Density of Mild Steel(kg/m^3)
v = 0.30; % Poissons Ratio of Mild Steel
R = 0.02; % Radius of Pipe (m)
E = 210*10^9; % Youngs Modulus of Mild Steel (pa)
a = (w.^2).*p;
b = (p.*(1-(v.^2)).*(R.^2).*(w.^2)-E);
c = (p.*(R.^2).*(w.^2)-E).*E;
k = sqrt((a.*b)./c); % k = Wave Number
L1=0.1;
L2=0.6;
L3=0.6;
Then you can use a for loop to calculate the D matrix and a cell array to store the results:
results = cell(1, length(k));
for i = 1:length(k)
results{i} = [
0,0,exp(-k(i)*L1),exp(-k(i)*L2),0,0;...
exp(-k(i)*L1),1,exp(-k(i)*L1),exp(-k(i)*L2),0,0;...
-k(i)*exp(-k(i)*L1),k(i),k(i)*exp(-k(i)*L1),-k(i)*exp(-k(i)*L2),0,0;...
0,0,exp(-k(i)*(L1+L2)),k(i),-exp(-k(i)*(L1+L2)),-exp(-k(i)*L3);...
0,0,-k(i)*exp(-k(i)*(L1+L2)),1,k(i)*exp(-k(i)*(L1+L2)),k(i)*exp(-k(i)*L3);...
0,0,exp(-k(i)*(L1+L2)),1,0,0
]
end
P.S. Without trying to get on to you, I think that what you just want is to someone solve an excercise for you. If this is not the case, ignore my p.s.

Substituting values of a matrix

Say I have the following two matrices:
>> x = [1 4 3; 6 4 3; 6 9 3; 2 4 3; 5 4 0; 5 3 1; 6 4 7];
>> y = [0 0 1; 1 1 0; 1 1 0; 0 1 1; 0.2 0.8 0.54; 1 1 1; 0 0 0];
Where you can think of x as some image, and y the degree of membership of of each element of x to some region of interest.
Say I set those elements in x that have degree of membership = 1 to 1 and the other elements to 0 as follows:
x = zeros(size(y));
x(y==1) = 1;
In which case I will have the following output:
0 0 1
1 1 0
1 1 0
0 1 1
0 0 0
1 1 1
0 0 0
Now, for the elements of 0, how can I substitute their values with the value of y in the corresponding location?
Thanks.
Try this:
x(x==0)=y(x==0);
Ans:
x =
0 0 1.0000
1.0000 1.0000 0
1.0000 1.0000 0
0 1.0000 1.0000
0.2000 0.8000 0.5400
1.0000 1.0000 1.0000
0 0 0