[1fedde]: / Thoracic Organs Segmentation code / RibCageApproximation.m

Download this file

167 lines (118 with data), 5.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
function [FinalCurve]=RibCageApproximation(I,Thres);
%Draw a closed curve which approximates the cross
%section of the rib cage in CT slices.
% [FinalCurve]=RibCageApproximation(I,Thres);
% Input parameters
% Img=> the CT slice
% Thres=> the desired threshold for the ribs (bones) extraction.
Img=squeeze(I);
%apply threshold
BinaryImage=Img>Thres;
%perform morphological open operation
BinaryImage = imopen(BinaryImage,strel([1 1;1 1]));
%find the pixels of the rib cage.
[x,y]=find(BinaryImage==1);
%define the center of the image.
ImgCenter =round( [size(BinaryImage)]./2);
%Estimate the vector between bone pixels and image centre
vector = [x-ImgCenter(1),y-ImgCenter(2)];
%Vector's angle in degrees.
Angle = mod(360+180/pi*atan2(vector(:,2),vector(:,1)),360);
%In each directions (0, 10,...., 360 degrees), define the bone pixel which is closer to the image
%center and keep it for the interpolation process.
Theta=[0:10:360];k=0;
Ind=cell([length(Theta)-1,1]);
for i =1:length(Theta)-1
[Ind{i,1}] = find(Angle>=Theta(i) & Angle<Theta(i+1));
if ~isempty(Ind{i,1})
IndMinDist = FunctionMinDistance(x(Ind{i,1}),y(Ind{i,1}),ImgCenter(1),ImgCenter(2));
k=k+1;
IndOfMinDistance(k,1)=Ind{i,1}(IndMinDist(1),1);
end
end
%Set points with the minimum distance from the center of the ribs cavity in an order
[xi, yi]=PixelsInOrder(x(IndOfMinDistance),y(IndOfMinDistance),ImgCenter(1),ImgCenter(2));
%Cubic interpolation
[xii, yii] = Curvefitting(xi,yi,0.2);
xii = round(xii);yii=round(yii);
%Draw the final curve
FinalCurve=zeros(size(BinaryImage));
for i =1:length(xii)
FinalCurve(xii(i),yii(i))=1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function IndOfMinDistance = FunctionMinDistance(I,J,c1,c2)
%This function calculates the distance between each contour (I,J) point and
%the centre of the contour
%and finds the edge with the minimum distance
% IndOfMinDistance = FunctionMinDistance(I,J,c1,c2)
% Input Parameters
% [I,J] points coordinates
% [c1,c2] coordinates of the centre of the contour
MinDistance = zeros(length(I),1);
MinDistance(:) = sqrt((I(:)-c1).^2+(J(:)-c2).^2);
IndOfMinDistance =find (MinDistance <= min (MinDistance));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Final_x, Final_y]=PixelsInOrder(x,y,c1,c2);
%Define a cartesian system xy with center[c1,c2],
%Set the points [x,y] in a circular order according to theirs angles
% [Final_x, Final_y]=PixelsInOrder(x,y,c1,c2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
c1=round(c1);c2=round(c2);
vector = [x-c1,y-c2];
%estimate the angle between the cartesian axis x and the points [x,y]
Theta = mod(360+180/pi*atan2(vector(:,2),vector(:,1)),360);
%sort the [x,y] points
[ThetaSorted,Ind] = sort(Theta);
Final_x=zeros(length(x),1);
Final_y=zeros(length(y),1);
Final_x(1:length(x)) =x(Ind);
Final_y(1:length(y)) =y(Ind);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [xi,yi] = Curvefitting(x,y,RES)
% Interpolate(cubic) the points of the image in order to create a close curve
% [xi,yi] =Curvefitting(x,y,RES)
%
% RES: resolution desired
%
% Modified Code by A. Koulouri
%
% Chenyang Xu and Jerry L. Prince, 3/8/96, 6/17/97
% Copyright (c) 1996-97 by Chenyang Xu and Jerry L. Prince
% Image Analysis and Communications Lab, Johns Hopkins University
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% convert to column vector
x = x(:); y = y(:);
N = length(x);
% make it a circular list since we are dealing with closed contour
x = [x;x(1)];
y = [y;y(1)];
dx = x([2:N+1])- x(1:N);
dy = y([2:N+1])- y(1:N);
d = sqrt(dx.*dx+dy.*dy); % compute the distance from previous node for point 2:N+1
d = [0;d]; % point 1 to point 1 is 0
% now compute the arc length of all the points from the first point [x(1),
% y(1)].
% we use matrix multiply to achieve summing
M = length(d);
d = (d'*uppertri(M,M))';
% now ready to reparametrize the closed curve in terms of arc length
maxd = d(M);
if (maxd/RES<3)
error('RES too big compare to the length of original curve');
end
di = 0:RES:maxd;
xi = interp1(d,x,di,'cubic');
yi = interp1(d,y,di,'cubic');
N = length(xi);
if (maxd - di(length(di)) <RES/2) % deal with end boundary condition
xi = xi(1:N-1);
yi = yi(1:N-1);
end
function X = uppertri(M,N)
% UPPERTRI Upper triagonal matrix
% UPPER(M,N) is a M-by-N triagonal matrix
[J,I] = meshgrid(1:M,1:N);
X = (J>=I);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%