17 #ifndef __itkVoronoiSegmentationImageFilterBase_txx
18 #define __itkVoronoiSegmentationImageFilterBase_txx
28 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
29 VoronoiSegmentationImageFilterBase <TInputImage,TOutputImage,TBinaryPriorImage>
36 m_NumberOfSeeds = 200;
37 m_NumberOfSeedsToAdded = 0;
38 m_MeanDeviation = 0.8;
39 m_UseBackgroundInAPrior =
false;
40 m_OutputBoundary =
false;
41 m_InteractiveSegmentation =
false;
42 m_WorkingVD=VoronoiDiagram::New();
43 m_VDGenerator=VoronoiDiagramGenerator::New();
47 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
49 ::~VoronoiSegmentationImageFilterBase()
53 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
56 ::PrintSelf(std::ostream& os,
Indent indent)
const
58 Superclass::PrintSelf(os, indent);
59 os << indent <<
"Number Of Seeds: "
60 << m_NumberOfSeeds << std::endl;
62 os << indent <<
"Minimum Region for Split: "
63 << m_MinRegion << std::endl;
65 os << indent <<
"Number Of Steps to Run: (0 means runs until no region to split) "
66 << m_Steps << std::endl;
68 os << indent <<
"UseBackgroundInAPrior = " << m_UseBackgroundInAPrior << std::endl;
69 os << indent <<
"OutputBoundary = " << m_OutputBoundary << std::endl;
70 os << indent <<
"MeanDeviation = " << m_MeanDeviation << std::endl;
71 os << indent <<
"LastStepSeeds = " << m_LastStepSeeds << std::endl;
72 os << indent <<
"InteractiveSegmentation = " << m_InteractiveSegmentation << std::endl;
73 os << indent <<
"NumberOfSeedsToAdded = " << m_NumberOfSeedsToAdded
75 os << indent <<
"Size = " << m_Size << std::endl;
78 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
88 currP = vertlist.front();
90 leftP = vertlist.front();
91 while(currP[1] > leftP[1])
93 vertlist.push_back(currP);
94 currP=vertlist.front();
96 leftP=vertlist.front();
98 rightP=vertlist.back();
99 while(currP[1] > rightP[1])
101 vertlist.push_front(currP);
102 currP=vertlist.back();
104 rightP=vertlist.back();
106 leftP=vertlist.front();
109 if(leftP[0]>rightP[0])
111 while(!(vertlist.empty()))
113 tmpQ.push_back(vertlist.front());
114 vertlist.pop_front();
116 while(!(tmpQ.empty()))
118 vertlist.push_front(tmpQ.front());
123 leftP=vertlist.front();
124 rightP=vertlist.back();
126 double beginy=currP[1];
127 int intbeginy=(int)vcl_ceil(beginy);
129 double leftendy=leftP[1];
130 double rightendy=rightP[1];
131 double beginx=currP[0];
132 double endx=currP[0];
133 double leftDx,rightDx;
135 double leftheadx=beginx;
136 double rightheadx=endx;
137 double leftheady=beginy;
138 double rightheady=beginy;
143 if(leftendy>rightendy)
153 if (leftP[1]==beginy)
159 leftDx=(leftP[0]-beginx)/(leftP[1]-beginy);
162 if (rightP[1]==beginy)
168 rightDx=(rightP[0]-endx)/(rightP[1]-beginy);
171 int intendy=(int)vcl_floor(endy);
172 if(intbeginy>intendy)
183 else if((intbeginy==intendy) && (intbeginy==0))
193 for(i=static_cast<int>(vcl_ceil(beginx));i<=static_cast<int>(vcl_floor(endx));i++)
196 (*PixelPool).push_back(idx);
202 offset = (double)intbeginy-beginy;
203 endx += offset * rightDx;
204 beginx += offset * leftDx;
205 while(idx[1] <= intendy)
207 for(i=static_cast<int>(vcl_ceil(beginx)); i <= static_cast<int>(vcl_floor(endx)); i++)
210 (*PixelPool).push_back(idx);
219 int vsize =
static_cast<int>( vertlist.size() );
230 beginx=leftheadx+leftDx*(beginy-leftheady);
231 rightP=vertlist.back();
232 if ((rightP[1]==currP[1]))
238 rightDx=(rightP[0]-currP[0])/(rightP[1]-currP[1]);
243 vertlist.pop_front();
248 endx=rightheadx+rightDx*(beginy-rightheady);
249 leftP=vertlist.front();
250 if ((leftP[1]==currP[1]))
256 leftDx=(leftP[0]-currP[0])/(leftP[1]-currP[1]);
262 if(leftendy>rightendy)
273 intendy=(int)vcl_floor(endy);
274 intbeginy=(int)vcl_ceil(beginy);
276 if(intbeginy>intendy)
289 offset = (double)intbeginy-beginy;
290 endx += offset * rightDx;
291 beginx += offset * leftDx;
292 while(idx[1] <= intendy)
294 for(i = static_cast<int>(vcl_ceil(beginx)); i <= static_cast<int>(vcl_floor(endx)); i++)
297 (*PixelPool).push_back(idx);
318 intbeginy=(int)vcl_ceil(beginy);
319 intendy=(int)vcl_floor(endy);
320 if(intbeginy<=intendy)
324 if ((rightP[1]==leftP[1]))
330 rightDx=(rightP[0]-leftP[0])/(rightP[1]-leftP[1]);
333 beginx=leftP[0]+leftDx*(rightP[1]-leftP[1]);
337 if ((rightP[1]==leftP[1]))
343 leftDx=(rightP[0]-leftP[0])/(rightP[1]-leftP[1]);
346 endx=rightP[0]+rightDx*(leftP[1]-rightP[1]);
348 offset = (double)intbeginy-beginy;
349 beginx += offset * leftDx;
350 endx += offset * rightDx;
351 while(idx[1] <= intendy)
353 for(i = static_cast<int>(vcl_ceil(beginx)); i <= static_cast<int>(vcl_floor(endx)); i++)
356 (*PixelPool).push_back(idx);
365 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
368 ::ClassifyDiagram(
void)
375 for(
int i=0;i<m_NumberOfSeeds;i++)
378 m_WorkingVD->GetCellId(i,currCell);
379 currPitEnd = currCell->PointIdsEnd();
381 for(currPit = currCell->PointIdsBegin(); currPit != currPitEnd; ++currPit)
383 m_WorkingVD->GetPoint((*currPit),&(currP));
384 VertList.push_back(currP);
388 this->GetPixelIndexFromPolygon(VertList,&PixelPool);
389 m_NumberOfPixels[i] =
static_cast<int>( PixelPool.size() );
390 m_Label[i] = this->TestHomogeneity(PixelPool);
393 m_NumberOfBoundary = 0;
394 for(
int i=0;i<m_NumberOfSeeds;i++)
403 while((it != itend) && (!bnd))
405 bnd = (m_Label[*it] == 1);
412 m_NumberOfBoundary++;
418 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
421 ::GenerateAddingSeeds(
void)
428 for(eit = m_WorkingVD->EdgeBegin();eit != eitend; ++eit)
430 seeds = m_WorkingVD->GetSeedsIDAroundEdge(&*eit);
431 if( ((m_Label[seeds[0]]==2)||(m_Label[seeds[1]]==2))
432 && (m_NumberOfPixels[seeds[0]]>m_MinRegion)
433 && (m_NumberOfPixels[seeds[1]]>m_MinRegion) )
435 adds[0] = (eit->m_Left[0] + eit->m_Right[0])*0.5;
436 adds[1] = (eit->m_Left[1] + eit->m_Right[1])*0.5;
437 m_SeedsToAdded.push_back(adds);
443 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
446 ::RunSegmentOneStep(
void)
448 m_NumberOfPixels.resize(m_NumberOfSeeds);
449 m_Label.resize(m_NumberOfSeeds);
450 m_SeedsToAdded.clear();
452 m_WorkingVD=m_VDGenerator->GetOutput();
453 this->ClassifyDiagram();
454 this->GenerateAddingSeeds();
455 m_NumberOfSeedsToAdded =
static_cast<int>( m_SeedsToAdded.size() );
457 if (m_InteractiveSegmentation)
461 this->MakeSegmentBoundary();
465 this->MakeSegmentObject();
470 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
478 unsigned long count=1;
479 this->RunSegmentOneStep();
481 this->UpdateProgress(static_cast<float>(count)
483 if(m_NumberOfBoundary == 0)
487 while( (m_NumberOfSeedsToAdded != 0) && ok)
490 m_VDGenerator->AddSeeds(m_NumberOfSeedsToAdded,m_SeedsToAdded.begin());
491 m_LastStepSeeds = m_NumberOfSeeds;
492 m_NumberOfSeeds += m_NumberOfSeedsToAdded;
493 this->RunSegmentOneStep();
495 this->UpdateProgress(static_cast<float>(count)
499 else if(m_Steps == 1)
501 this->RunSegmentOneStep();
502 this->UpdateProgress(1.0);
506 this->RunSegmentOneStep();
509 this->UpdateProgress(1.0);
513 this->UpdateProgress(1.0/static_cast<float>(m_Steps));
515 if(m_NumberOfBoundary == 0)
520 while((i<m_Steps) && ok)
522 m_VDGenerator->AddSeeds(m_NumberOfSeedsToAdded, m_SeedsToAdded.begin());
523 m_LastStepSeeds = m_NumberOfSeeds;
524 m_NumberOfSeeds += m_NumberOfSeedsToAdded;
525 this->RunSegmentOneStep();
527 this->UpdateProgress(static_cast<float>(i)/static_cast<float>(m_Steps));
532 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
539 ->SetBufferedRegion( this->GetOutput()->GetRequestedRegion() );
540 this->GetOutput()->Allocate();
543 m_Size = this->GetInput()->GetRequestedRegion().
GetSize();
548 m_VDGenerator->SetBoundary(VDsize);
549 m_VDGenerator->SetRandomSeeds(m_NumberOfSeeds);
554 this->MakeSegmentBoundary();
558 this->MakeSegmentObject();
563 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
566 ::BeforeNextStep(
void)
568 m_VDGenerator->AddSeeds(m_NumberOfSeedsToAdded, m_SeedsToAdded.begin());
569 m_LastStepSeeds = m_NumberOfSeeds;
570 m_NumberOfSeeds += m_NumberOfSeedsToAdded;
574 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
577 ::MakeSegmentBoundary(
void)
580 RegionType region = this->GetInput()->GetRequestedRegion();
590 for(
int i=0;i<m_NumberOfSeeds;i++)
594 nitend = m_WorkingVD->NeighborIdsEnd(i);
595 for(nit=m_WorkingVD->NeighborIdsBegin(i); nit != nitend; ++nit)
597 if(((*nit)>i)&&(m_Label[*nit]==2))
599 drawLine(m_WorkingVD->GetSeed(i),m_WorkingVD->GetSeed(*nit));
607 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
610 ::MakeSegmentObject(
void)
612 RegionType region = this->GetInput()->GetRequestedRegion();
623 for(
int i=0;i<m_NumberOfSeeds;i++)
628 m_WorkingVD->GetCellId(i, currCell);
629 currPitEnd = currCell->PointIdsEnd();
631 for(currPit = currCell->PointIdsBegin(); currPit != currPitEnd; ++currPit)
633 m_WorkingVD->GetPoint((*currPit),&(currP));
634 VertList.push_back(currP);
636 FillPolygon(VertList);
641 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
651 currP = vertlist.front();
652 vertlist.pop_front();
653 leftP = vertlist.front();
654 while(currP[1] > leftP[1])
656 vertlist.push_back(currP);
657 currP=vertlist.front();
658 vertlist.pop_front();
659 leftP=vertlist.front();
661 rightP=vertlist.back();
662 while(currP[1] > rightP[1])
664 vertlist.push_front(currP);
665 currP=vertlist.back();
667 rightP=vertlist.back();
669 leftP=vertlist.front();
672 if(leftP[0]>rightP[0])
674 while(!(vertlist.empty()))
676 tmpQ.push_back(vertlist.front());
677 vertlist.pop_front();
679 while(!(tmpQ.empty()))
681 vertlist.push_front(tmpQ.front());
686 leftP=vertlist.front();
687 rightP=vertlist.back();
689 double beginy=currP[1];
690 int intbeginy=(int)vcl_ceil(beginy);
692 double leftendy=leftP[1];
693 double rightendy=rightP[1];
694 double beginx=currP[0];
695 double endx=currP[0];
696 double leftDx,rightDx;
698 double leftheadx=beginx;
699 double rightheadx=endx;
700 double leftheady=beginy;
701 double rightheady=beginy;
706 if(leftendy>rightendy)
722 leftDx=(leftP[0]-beginx)/(leftP[1]-beginy);
724 if(rightP[1]==beginy)
730 rightDx=(rightP[0]-endx)/(rightP[1]-beginy);
732 int intendy=(int)vcl_floor(endy);
733 if(intbeginy>intendy)
744 else if((intbeginy==intendy) && (intbeginy==0))
754 for(i=static_cast<int>(vcl_ceil(beginx));i<=static_cast<int>(vcl_floor(endx));i++)
757 this->GetOutput()->SetPixel(idx,color);
763 offset = (double)intbeginy-beginy;
764 endx += offset * rightDx;
765 beginx += offset * leftDx;
766 while(idx[1] <= intendy)
768 for(i = static_cast<int>(vcl_ceil(beginx)); i <= static_cast<int>(vcl_floor(endx)); i++)
771 this->GetOutput()->SetPixel(idx,color);
780 int vsize =
static_cast<int>( vertlist.size() );
791 beginx=leftheadx+leftDx*(beginy-leftheady);
792 rightP=vertlist.back();
793 if (rightP[1] == currP[1])
799 rightDx=(rightP[0]-currP[0])/(rightP[1]-currP[1]);
804 vertlist.pop_front();
809 endx=rightheadx+rightDx*(beginy-rightheady);
810 leftP=vertlist.front();
811 if (leftP[1] == currP[1])
817 leftDx=(leftP[0]-currP[0])/(leftP[1]-currP[1]);
823 if(leftendy>rightendy)
834 intendy=(int)vcl_floor(endy);
835 intbeginy=(int)vcl_ceil(beginy);
837 if(intbeginy>intendy)
850 offset = (double)intbeginy-beginy;
851 endx += offset * rightDx;
852 beginx += offset * leftDx;
853 while(idx[1] <= intendy)
855 for(i = static_cast<int>(vcl_ceil(beginx)); i <= static_cast<int>(vcl_floor(endx)); i++)
858 this->GetOutput()->SetPixel(idx,color);
879 intbeginy=(int)vcl_ceil(beginy);
880 intendy=(int)vcl_floor(endy);
881 if(intbeginy<=intendy)
885 if (rightP[1] == leftP[1])
891 rightDx=(rightP[0]-leftP[0])/(rightP[1]-leftP[1]);
894 beginx=leftP[0]+leftDx*(rightP[1]-leftP[1]);
898 if (rightP[1] == leftP[1])
904 leftDx=(rightP[0]-leftP[0])/(rightP[1]-leftP[1]);
907 endx=rightP[0]+rightDx*(leftP[1]-rightP[1]);
909 offset = (double)intbeginy-beginy;
910 beginx += offset * leftDx;
911 endx += offset * rightDx;
912 while(idx[1] <= intendy)
914 for(i = static_cast<int>(vcl_ceil(beginx)); i <= static_cast<int>(vcl_floor(endx)); i++)
917 this->GetOutput()->SetPixel(idx,color);
927 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
932 int x1=(int)(p1[0]+0.5);
933 int x2=(int)(p2[0]+0.5);
934 int y1=(int)(p1[1]+0.5);
935 int y2=(int)(p2[1]+0.5);
936 if(x1==static_cast<int>(m_Size[0])) x1--;
937 if(x2==static_cast<int>(m_Size[0])) x2--;
938 if(y1==static_cast<int>(m_Size[1])) y1--;
939 if(y2==static_cast<int>(m_Size[1])) y2--;
943 int adx=(dx>0)?dx:-dx;
945 int ady=(dy>0)?dy:-dy;
953 save=x1; x1=x2; x2=save;
961 float offset=(float)dy/dx;
962 for(
int i=x1;i<=x2;i++)
966 this->GetOutput()->SetPixel(idx,1);
976 save=y1; y1=y2; y2=save;
983 float offset=(float)dx/dy;
984 for(
int i=y1;i<=y2;i++)
988 this->GetOutput()->SetPixel(idx,1);
996 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
1000 unsigned char outcolor,
unsigned char boundcolor)
1003 RegionType region = this->GetInput()->GetRequestedRegion();
1015 for(eit = m_WorkingVD->EdgeBegin();eit != eitend; ++eit)
1017 seeds = m_WorkingVD->GetSeedsIDAroundEdge(&*eit);
1018 if((m_Label[seeds[0]]==2)||(m_Label[seeds[1]]==2))
1020 drawVDline(result,eit->m_Left,eit->m_Right,boundcolor);
1022 else if(m_Label[seeds[0]])
1024 drawVDline(result,eit->m_Left,eit->m_Right,incolor);
1028 drawVDline(result,eit->m_Left,eit->m_Right,outcolor);
1034 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
1038 unsigned char color)
1040 int x1=(int)(p1[0]+0.5);
1041 int x2=(int)(p2[0]+0.5);
1042 int y1=(int)(p1[1]+0.5);
1043 int y2=(int)(p2[1]+0.5);
1044 if(x1==(
int)m_Size[0])
1048 if(x2==(
int)m_Size[0])
1052 if(y1==(
int)m_Size[1])
1056 if(y2==(
int)m_Size[1])
1061 int adx=(dx>0)?dx:-dx;
1063 int ady=(dy>0)?dy:-dy;
1071 save=x1; x1=x2; x2=save;
1072 save=y1; y1=y2; y2=save;
1079 float offset=(float)dy/dx;
1080 for(
int i=x1;i<=x2;i++)
1084 result->SetPixel(idx,color);
1093 save=x1; x1=x2; x2=save;
1094 save=y1; y1=y2; y2=save;
1101 float offset=(float)dx/dy;
1102 for(
int i=y1;i<=y2;i++)
1106 result->SetPixel(idx,color);
1113 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
1116 ::GenerateInputRequestedRegion()
1119 Superclass::GenerateInputRequestedRegion();
1127 input->SetRequestedRegion( this->GetInput()->GetLargestPossibleRegion() );
1132 template <
class TInputImage,
class TOutputImage,
class TBinaryPriorImage>
1138 Superclass::EnlargeOutputRequestedRegion(output);
1142 ->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() );