CHOU

[Abe先生の授業] Image Processing - 라벨링 알고리즘(Labeling Algorithm) 구현해 보기(Chapter2) 본문

Tech/Technical Tips

[Abe先生の授業] Image Processing - 라벨링 알고리즘(Labeling Algorithm) 구현해 보기(Chapter2)

chobabo 2009. 5. 1. 22:00


 기존에 많이 사용되고 널리 알려진 Glassfire Algorithm을 저도 주로 사용해 왔었는데, 이번에 Professor Abe 께서 숙제로 내주신 라벨링 알고리즘은 Glassfire Algorithm과 비슷한거 같지만 약간 독특한 법칙으로 변환을 시키는거 같습니다. 다음주 5월 7일까지 만들어야 하는데.. 우선은 오늘 1차 개선되지 않은 버전으로 만들어 봤습니다. 아래는 2009-04-30 일날 수업한 라벨링 알고리즘에 대한 내용 입니다.

아래 문서는 2*2 배열을 이용하여 라벨링 알고리즘을 하라는 내용입니다. 이때 약간의 규칙성을 부여하여 맨 아래에 있는 내용과 같은 경우가 해당 될 때 마다 그 규칙을 적용하여 바꿔 주라는 내용 입니다.






위의 규칙을 적용하고 구글에서 Sequential Labeling Algorithm 도 참고 했습니다.

void CImageDlg::OnLabeling() //ラベリング処理
{

 parts.Labeling();

 Invalidate(false); //再描画

 CEdit *myEdit1 = (CEdit*)GetDlgItem(IDC_EDIT1); //結果表示用 SHAFT
 CEdit *myEdit2 = (CEdit*)GetDlgItem(IDC_EDIT4); //結果表示用 PLATE
 CEdit *myEdit3 = (CEdit*)GetDlgItem(IDC_EDIT5); //結果表示用 CAM

 //debug Edit
 CEdit *myEdit4 = (CEdit*)GetDlgItem(IDC_EDIT2); //結果表示用 CAM
 //=====================labeling funtion==========================//
 
 //--declare variable--//
 bool *labelOutPut = &parts.OUTPUT[0][0]; //import output image
 CString m_String; //convert integer to string

 int i, j, temp;
 int tempLabel = 0;

 int labelCount = 0;     //label Count

 int resultLabelValue = 0;

 int width = 320;
 int height = 240;

 int equal_table[240*320][2] = {0};  //initialization equal table

 //initialization coloring
 int *coloring = new int[width * height];
 
 for(i=0; i < width * height; i++)
  coloring[i] = 0;

 //------------------------First Scan Start---------------------------//
 int maxl=0, minl=0, min_eq=0;

 for(j=1; j<height; j++)
 {
  int IndexCount = j * width;

  for(i=1; i<width; i++)
  {
   int upperIndex = IndexCount + i - width;
   int leftIndex = IndexCount + i - 1;
   int currentIndex = IndexCount + i;

   //if...pixel value is 0 or false...
   if(labelOutPut[currentIndex] == 1)
   {
    if( (coloring[upperIndex] != 0) && (coloring[leftIndex] != 0) )
    { 
     //if two value is same...
     if( (coloring[upperIndex] == coloring[leftIndex]  ) )
     {
      coloring[currentIndex] = coloring[upperIndex];
     }//end if
     else
     {
      maxl = max(coloring[upperIndex], coloring[leftIndex]);
      minl = min(coloring[upperIndex], coloring[leftIndex]);

      coloring[currentIndex] = minl;

      //create equal table
      min_eq = min(equal_table[maxl][1], equal_table[minl][1]);

      equal_table[maxl][1] = min_eq;
      equal_table[minl][1] = min_eq;
     }//end else
    }//end if
    else if (coloring[upperIndex] != 0)
    {
     coloring[currentIndex] = coloring[upperIndex];
    }//end else if
    else if (coloring[leftIndex] != 0)
    {
     coloring[currentIndex] = coloring[leftIndex];
    }//end else if
    else
    {
     labelCount ++;
     coloring[currentIndex] = labelCount;
     equal_table[labelCount][0] = labelCount;
     equal_table[labelCount][1] = labelCount;
    }//end else
   }//end if
  }//end for i
 }//end for j
 
 //-----------------------equal table arrangement-------------------------//
 for(i=1; i <= labelCount; i++)
 {
  temp = equal_table[i][1];

  if(temp != equal_table[i][0])
  {
   equal_table[i][1] = equal_table[temp][1];
  }//end if
 }//end for i

 int *hash = new int[labelCount + 1];

 memset(hash, 0, sizeof(int)*(labelCount+1) );

 for(i=1; i <= labelCount; i++)
 {
  hash[equal_table[i][1]] = equal_table[i][1];
 }//end for i

 int cnt = 1;

 for(i=1; i<= labelCount; i++)
 {
  if(hash[i] != 0)
  {
   hash[i] = cnt++;
  }//end if
 }//end for i

 for(i=1; i<= labelCount; i++)
 {
  equal_table[i][1] = hash[equal_table[i][1]];
 }//end for i

 delete [] hash;

 //resultLabelValue = equal_table[1][1];


 //------------------------Second Scan------------------------------//
 //labeling count and reDraw the image

 for(i=0; i < width * height; i++)
 {
  if(i == 0)
  {
   tempLabel = equal_table[i][1];
  }//end if

  if(tempLabel < equal_table[i][1])
  {
   tempLabel = equal_table[i][1];
  }//end if
  
 }//end for i
 

 //display on edit1
 m_String.Format("%d", tempLabel);  //covert int to string
 myEdit1->SetWindowText(m_String);  //display myEdit1


 //delete
 delete[] coloring;
}


 Visual Studio 6.0 C++ 로 프로그래밍 하였는데.. 수업이 다 좋은데 6.0 버전은 너무 오랜만에 사용하는거라 약간 툴이 익숙치 않고, 전부 일본어로 되어 있어서 설정하는데 무지 애먹었습니다^^; 개선된 버전은 좀 더 해보고 올리도록 하겠습니다.


Reference

1. Source Code Zip File



2.  ラベリング処理



3. Google Book(69-71p)
http://books.google.com/books?id=jpX...2oNxcbaYhIfAyw