-
Notifications
You must be signed in to change notification settings - Fork 0
/
cropneck.h
191 lines (154 loc) · 6.25 KB
/
cropneck.h
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include "itkBinaryImageToShapeLabelMapFilter.h"
#include "itkLabelImageToShapeLabelMapFilter.h"
#include "itkLabelMapToBinaryImageFilter.h"
template <class RawImType>
void cropNeck(typename RawImType::Pointer raw, float distance, int &outtop, int &outbottom)
{
// simple neck blanking - find the top of head, go distance down and
// then start blanking
typedef typename itk::Image<unsigned char, RawImType::ImageDimension> MaskImType;
itk::Instance<itk::OtsuThresholdImageFilter <RawImType, MaskImType> > Thresh;
itk::Instance<itk::BinaryShapeKeepNObjectsImageFilter<MaskImType> > discarder;
Thresh->SetInput(raw);
Thresh->SetInsideValue(0);
Thresh->SetOutsideValue(1);
discarder->SetNumberOfObjects(1);
discarder->SetInput(Thresh->GetOutput());
discarder->SetForegroundValue(1);
typename MaskImType::Pointer mask = discarder->GetOutput();
mask->Update();
mask->DisconnectPipeline();
// find the top
typedef typename itk::BinaryImageToShapeLabelMapFilter<MaskImType> LabellerType;
typename LabellerType::Pointer labeller = LabellerType::New();
labeller->SetInput(mask);
labeller->SetFullyConnected(true);
labeller->SetInputForegroundValue(1);
typedef typename LabellerType::OutputImageType LabelMapType;
typedef typename LabellerType::OutputImagePointer LabelMapPointerType;
typedef typename LabelMapType::LabelObjectType LabelObjectType;
writeImDbg<MaskImType>(mask, "cropmask");
LabelMapPointerType labmap = labeller->GetOutput();
labmap->Update();
labmap->DisconnectPipeline();
// can only be one object
LabelObjectType * labelObject = labmap->GetLabelObject(1);
typename MaskImType::RegionType bb = labelObject->GetBoundingBox();
typename RawImType::SpacingType sp = raw->GetSpacing();
int top = bb.GetIndex()[2] + bb.GetSize()[2] - 1;
int bottom = top - distance/sp[2];
// std::cout << "bb= " << bb << std::endl;
// std::cout << "bottom= " << bottom << std::endl;
if (bottom > 0)
{
// blank all slices below
typename RawImType::RegionType blank = raw->GetLargestPossibleRegion();
typename RawImType::RegionType::SizeType s = blank.GetSize();
s[2] = bottom;
blank.SetSize(s);
fillRegion<RawImType>(raw, blank, 0);
fillRegion<MaskImType>(mask, blank, 0);
}
else
{
bottom = 0;
}
// trial clipping extreme values
std::vector<float> q;
q.push_back(0.75);
std::vector<typename RawImType::PixelType> v = computeImQuantile<RawImType, MaskImType>(raw, mask, q);
itk::Instance<itk::ThresholdImageFilter<RawImType> > resetBright;
resetBright->SetInput(raw);
resetBright->ThresholdAbove(v[0]);
resetBright->SetOutsideValue(v[0]);
typename RawImType::Pointer r = resetBright->GetOutput();
r->Update();
r->DisconnectPipeline();
raw=r;
writeImDbg<RawImType>(raw, "cropraw");
outbottom=bottom;
outtop=top;
}
// alternative version that estimates x/y centroid
// distance is the distance from top to where we start blanking neck
// slice is the thickness of the region at the top we will use to
// estimate x/y centroid
template <class RawImType>
void cropNeck2(typename RawImType::Pointer raw, float distance, float slice, int &outtop, int &outbottom, int &x, int &y)
{
// simple neck blanking - find the top of head, go distance down and
// then start blanking
typedef typename itk::Image<unsigned char, RawImType::ImageDimension> MaskImType;
itk::Instance<itk::OtsuThresholdImageFilter <RawImType, MaskImType> > Thresh;
itk::Instance<itk::BinaryShapeKeepNObjectsImageFilter<MaskImType> > discarder;
Thresh->SetInput(raw);
Thresh->SetInsideValue(0);
Thresh->SetOutsideValue(1);
discarder->SetNumberOfObjects(1);
discarder->SetInput(Thresh->GetOutput());
discarder->SetForegroundValue(1);
typename MaskImType::Pointer mask = discarder->GetOutput();
mask->Update();
mask->DisconnectPipeline();
// find the top
typedef typename itk::BinaryImageToShapeLabelMapFilter<MaskImType> LabellerType;
typename LabellerType::Pointer labeller = LabellerType::New();
labeller->SetInput(mask);
labeller->SetFullyConnected(true);
labeller->SetInputForegroundValue(1);
typedef typename LabellerType::OutputImageType LabelMapType;
typedef typename LabellerType::OutputImagePointer LabelMapPointerType;
typedef typename LabelMapType::LabelObjectType LabelObjectType;
writeImDbg<MaskImType>(mask, "cropmask");
LabelMapPointerType labmap = labeller->GetOutput();
labmap->Update();
labmap->DisconnectPipeline();
// can only be one object
LabelObjectType * labelObject = labmap->GetLabelObject(1);
typename MaskImType::RegionType bb = labelObject->GetBoundingBox();
typename RawImType::SpacingType sp = raw->GetSpacing();
int top = bb.GetIndex()[2] + bb.GetSize()[2] - 1;
int bottom = top - distance/sp[2];
// std::cout << "bb= " << bb << std::endl;
// std::cout << "bottom= " << bottom << std::endl;
if (bottom > 0)
{
// blank all slices below
typename RawImType::RegionType blank = raw->GetLargestPossibleRegion();
typename RawImType::RegionType::SizeType s = blank.GetSize();
s[2] = bottom;
blank.SetSize(s);
fillRegion<RawImType>(raw, blank, 0);
fillRegion<MaskImType>(mask, blank, 0);
}
else
{
bottom = 0;
}
outbottom=bottom;
outtop=top;
{
// estimate the centroid using the top 15mm
typedef typename itk::LabelImageToShapeLabelMapFilter<MaskImType> LabellerTypeB;
typename LabellerTypeB::Pointer labellerB = LabellerTypeB::New();
typedef typename LabellerTypeB::OutputImageType LabelMapTypeB;
typedef typename LabellerTypeB::OutputImagePointer LabelMapPointerTypeB;
typedef typename LabelMapTypeB::LabelObjectType LabelObjectTypeB;
typename MaskImType::RegionType blank = mask->GetLargestPossibleRegion();
typename MaskImType::RegionType::SizeType s = blank.GetSize();
s[2] = top - slice/sp[2];
blank.SetSize(s);
fillRegion<MaskImType>(mask, blank, 0);
writeImDbg<MaskImType>(mask, "topmask");
labellerB->SetInput(mask);
LabelMapPointerTypeB labmapB = labellerB->GetOutput();
labmapB->Update();
labmapB->DisconnectPipeline();
LabelObjectTypeB * labelObjectB = labmapB->GetLabelObject(1);
typename MaskImType::PointType cent = labelObjectB->GetCentroid();
typename MaskImType::IndexType ind;
mask->TransformPhysicalPointToIndex(cent, ind);
x=ind[0];
y=ind[1];
}
}