18 #ifndef __itkSharedMorphologyUtilities_txx
19 #define __itkSharedMorphologyUtilities_txx
36 template <
class TRegion,
class TLine>
48 typename TRegion::IndexType ISt = AllImage.GetIndex();
50 typename TRegion::SizeType FSz = face.GetSize();
51 typename TRegion::IndexType FSt = face.GetIndex();
53 unsigned smallDim = 0;
54 for (
unsigned i = 0; i < AllImage.GetImageDimension(); i++)
62 long startI = ISt[smallDim];
63 long facePos = FSt[smallDim] + FSz[smallDim] - 1;
64 if (facePos == startI)
67 if (line[smallDim] > 0.000001)
return true;
73 if (line[smallDim] < -0.000001)
return true;
78 template <
class TImage,
class TBres,
class TLine>
82 const typename TBres::OffsetArray LineOffsets,
83 const typename TImage::RegionType AllImage,
88 typename TImage::IndexType ImStart = AllImage.GetIndex();
89 typename TImage::SizeType ImSize = AllImage.GetSize();
90 float Tfar = NumericTraits<float>::max();
91 float Tnear = NumericTraits<float>::NonpositiveMin();
92 float domdir = NumericTraits<float>::NonpositiveMin();
95 for (
unsigned i = 0; i< TImage::RegionType::ImageDimension; i++)
97 if (vcl_fabs(line[i]) > domdir)
99 domdir = vcl_fabs(line[i]);
102 if (vcl_fabs(line[i]) > tol)
104 int P1 = ImStart[i] - StartIndex[i];
105 int P2 = ImStart[i] + ImSize[i] - 1 - StartIndex[i];
106 float T1 = ((float)(P1))/line[i];
107 float T2 = ((float)(P2))/line[i];
127 if ((StartIndex[i] < ImStart[i]) || (StartIndex[i] > ImStart[i] + (
int)ImSize[i] - 1))
135 sPos = (int)(Tnear*vcl_fabs(line[perpdir]) + 0.5);
136 ePos = (int)(Tfar*vcl_fabs(line[perpdir]) + 0.5);
142 bool intersection =
false;
144 if (Tnear - Tfar < 10)
148 assert(sPos < (
int)LineOffsets.size());
149 for (
int i = ePos; i<= sPos; i++)
151 if (AllImage.IsInside(StartIndex + LineOffsets[i]))
162 sPos = ePos = inside;
163 assert(ePos + 1 >= 0);
164 assert(ePos + 1 < (
int)LineOffsets.size());
165 while (AllImage.IsInside(StartIndex + LineOffsets[ePos + 1]))
168 assert(ePos + 1 >= 0);
169 assert(ePos + 1 < (
int)LineOffsets.size());
171 assert(sPos - 1 >= 0);
172 assert(sPos - 1 < (
int)LineOffsets.size());
173 while (AllImage.IsInside(StartIndex + LineOffsets[sPos - 1]))
176 assert(sPos - 1 >= 0);
177 assert(sPos - 1 < (
int)LineOffsets.size());
193 assert(sPos < (
int)LineOffsets.size());
194 if (AllImage.IsInside(StartIndex + LineOffsets[sPos]))
198 assert(sPos - 1 >= 0);
199 assert(sPos - 1 < (
int)LineOffsets.size());
200 if (!AllImage.IsInside(StartIndex + LineOffsets[sPos - 1]))
break;
206 for(;sPos<(int)LineOffsets.size();)
209 assert(sPos < (
int)LineOffsets.size());
211 if (!AllImage.IsInside(StartIndex + LineOffsets[sPos])) ++sPos;
215 if (AllImage.IsInside(StartIndex + LineOffsets[ePos]))
217 for(;ePos<(int)LineOffsets.size();)
219 assert(ePos + 1 >= 0);
220 assert(ePos + 1 < (
int)LineOffsets.size());
221 if (!AllImage.IsInside(StartIndex + LineOffsets[ePos + 1]))
break;
231 assert(ePos < (
int)LineOffsets.size());
232 if (!AllImage.IsInside(StartIndex + LineOffsets[ePos])) --ePos;
243 template <
class TImage,
class TBres>
245 const typename TImage::IndexType StartIndex,
246 const typename TBres::OffsetArray LineOffsets,
247 const typename TImage::PixelType * outbuffer,
248 const unsigned start,
251 unsigned size = end - start + 1;
252 for (
unsigned i = 0; i <size; i++)
254 assert(start + i >= 0);
255 assert(start + i < LineOffsets.size());
257 output->SetPixel(StartIndex + LineOffsets[start + i], outbuffer[i+1]);
259 typename TImage::IndexType I = StartIndex + LineOffsets[start + i];
260 output->SetPixel(I, 1 + output->GetPixel(I));
266 template <
class TInputImage,
class TLine>
267 typename TInputImage::RegionType
269 const typename TInputImage::RegionType AllImage,
276 FaceCalculatorType faceCalculator;
277 typename TInputImage::SizeType radius;
279 typename FaceCalculatorType::FaceListType faceList;
280 faceList = faceCalculator(input, AllImage, radius);
281 typename FaceCalculatorType::FaceListType::iterator fit;
282 fit = faceList.begin();
289 typedef typename TInputImage::RegionType RegionType;
290 typedef typename TInputImage::SizeType SizeType;
291 typedef typename TInputImage::IndexType IndexType;
292 typedef std::list<RegionType> FaceListType;
293 FaceListType faceList;
295 for (
unsigned i = 0; i < TInputImage::ImageDimension; i++)
298 SizeType S1 = AllImage.GetSize();
299 IndexType I2 = AllImage.GetIndex();
309 I2[i] = I2[i] + AllImage.GetSize()[i] - 1;
312 faceList.push_back(R1);
313 faceList.push_back(R2);
316 typename FaceListType::iterator fit;
317 fit = faceList.begin();
319 typename TInputImage::RegionType RelevantRegion;
320 bool foundFace =
false;
321 float MaxComp = NumericTraits<float>::NonpositiveMin();
325 for (
unsigned i = 0;i< TInputImage::RegionType::ImageDimension;i++)
327 if (vcl_fabs(line[i]) > MaxComp)
329 MaxComp = vcl_fabs(line[i]);
334 for (;fit != faceList.end();++fit)
339 unsigned FaceDir = 0;
341 for (
unsigned i = 0;i< TInputImage::RegionType::ImageDimension;i++)
343 if (fit->GetSize()[i] == 1) FaceDir = i;
345 if (FaceDir == DomDir)
348 if ( NeedToDoFace<ITK_TYPENAME TInputImage::RegionType, TLine>(AllImage, *fit, line) )
351 RelevantRegion = *fit;
362 unsigned NonFaceDim = 0;
364 for (
unsigned i = 0; i < TInputImage::RegionType::ImageDimension;i++)
366 if (RelevantRegion.GetSize()[i] == 1)
374 typename TInputImage::SizeType NewSize = RelevantRegion.GetSize();
375 typename TInputImage::IndexType NewStart = RelevantRegion.GetIndex();
376 unsigned NonFaceLen = AllImage.GetSize()[NonFaceDim];
377 for (
unsigned i = 0; i < TInputImage::RegionType::ImageDimension;i++)
381 int Pad = Math::Ceil<int>((float)(NonFaceLen) * line[i]/vcl_fabs(line[NonFaceDim]));
385 NewSize[i] += abs(Pad) + 1;
390 NewSize[i] += Pad + 1;
391 NewStart[i] -= Pad + 1;
395 RelevantRegion.SetSize(NewSize);
396 RelevantRegion.SetIndex(NewStart);
400 std::cout <<
"Line " << line <<
" doesnt correspond to a face" << std::endl;
405 return RelevantRegion;
408 template <
class TImage,
class TBres,
class TLine>
410 const typename TImage::IndexType StartIndex,
413 const typename TBres::OffsetArray LineOffsets,
414 const typename TImage::RegionType AllImage,
415 typename TImage::PixelType * inbuffer,
429 for (start=0;start < LineOffsets.size();++start)
431 if (AllImage.IsInside(StartIndex + LineOffsets[start]))
break;
434 int status = ComputeStartEnd<TImage, TBres, TLine>(StartIndex, line, tol, LineOffsets, AllImage,
436 if (!status)
return(status);
439 unsigned size = end - start + 1;
441 for (
unsigned i = 0; i < size;i++)
443 assert(start + i >= 0);
444 assert(start + i < LineOffsets.size());
445 inbuffer[i+1] = input->GetPixel(StartIndex + LineOffsets[start + i]);
449 ItType it(input, AllImage);
450 it.SetIndex(StartIndex);
451 for (
unsigned i = 0; i < lastPos;i++)
453 inbuffer[i]= it.Get();
455 assert(i < LineOffsets.size());
456 typename TImage::IndexType I = StartIndex + LineOffsets[i];
457 typename TImage::OffsetType Off = I - it.GetIndex();
464 template <
class TLine>
467 float N = line.GetNorm();
468 float correction = 0.0;
470 for (
unsigned int i = 0; i < TLine::Dimension; i++)
472 float tt = vcl_fabs(line[i]/N);
473 if (tt > correction) correction=tt;
477 return (
int)(N + 0.5);