2014-01-26 5 views
0

연결된 구성 요소 레이블링 알고리즘을 작성하려고했지만 원하는 결과를 얻지 못했습니다. 지금은 3 개의 장미가 겹쳐져 있지 않은 이미지가 있고 각각의 장미에 고유 한 회색 값을 붙이고 싶습니다. 라벨링 알고리즘을 적용하기 전에 배경을 제거하고 장미 만 유지하기 위해 임계 값을 사용합니다. 장미는 회색 값 1 (완전히 흰색 임)을 얻고 배경은 회색 값 0 (검정)을 얻습니다. 다음은이 모양의 이미지입니다. image연결된 구성 요소 레이블 지정 알고리즘에 문제가 있음

이렇게 한 후 라벨 알고리즘을 적용합니다. 그것은 주어진 레이블에 따라 장미에 세 가지 다른 회색 값을 부여해야합니다. 그러나 알고리즘은 첫 번째 두 장미 위에이 이상한 종류의 그라디언트 패턴을 만듭니다. 마지막 하나는 단일 회색 값인 것처럼 보입니다. 이미지는 다음과 같습니다. image

알고리즘이 복잡해 보이지만 실제로는 매우 간단합니다. 먼저 열과 행을 반복하고 배경이 아닌 각 픽셀에 대해 이웃이 이미 레이블링되어 있는지 확인합니다 (objectArray 값이 0이 아님을 의미). 그렇다면 이웃 목록에 추가하십시오. 그런 다음이 목록이 비어 있지 않은지 확인합니다. 개체 값을 증가시키고 현재 픽셀의 레이블 값에 값을 할당하고 현재 픽셀의 부모 값을이 고유 레이블로 설정하면 현재 픽셀에 고유 한 레이블을 지정합니다. 비어 있지 않으면 이웃 목록의 가장 작은 레이블 값을 결정하고 모든 이웃의 부모 값을이 레이블 값으로 설정하고 현재 픽셀의 레이블과 부모 값을이 레이블 값으로 설정합니다. 전체 이미지가 레이블링 될 때까지 모든 픽셀에 대해이 작업을 반복합니다.

일단 이것이 끝나면 픽셀 값을 다시 재귀합니다. 이번에는 각 픽셀의 레이블 값을 부모 값으로 설정합니다. 그런 다음 레이블 값에 따라 픽셀에 새 회색 값을 지정합니다.

왜 알고리즘이 장미에 제대로 레이블을 지정하지 않는지 이해할 수 없습니다. 아무도 나를 도울 수 있습니까? 세 번째 이웃을 검사 할 때 인덱스 오류가있어

public void label() 
{ 
    int objects = 1; 
    int[,] objectArray = new int[colors.GetLength(1), colors.GetLength(0)]; 
    DisjointSets disjointSet = new DisjointSets(); 
    int[,] parents = new int[colors.GetLength(1), colors.GetLength(0)]; 
    List<List<int>> eqSet = new List<List<int>>(); 
    for (int i = 0; i < colors.GetLength(1); i++) for (int j = 0; j < colors.GetLength(0); j++) 
    { 
     if (this[i, j].Gray == 1) 
     { 
      List<Label> neighbors = new List<Label>(); 
      if (i > 0) 
      { 
       if (this[i - 1, j].Gray == 1) 
       { 
        if (objectArray[i - 1, j] != 0) 
        { 
         neighbors.Add(new Label(i - 1, j, 0)); 
        } 
       } 
       if (j > 0) 
       { 
        if (this[i - 1, j - 1].Gray == 1) 
        { 
         if (objectArray[i - 1, j - 1] != 0) 
         { 
          neighbors.Add(new Label(i - 1, j - 1, 0)); 
         } 
        } 
       } 
       if (j < colors.GetLength(0)) 
       { 
        if (this[i - 1, j + 1].Gray == 1) 
        { 
         if (objectArray[i - 1, j] != 0) 
         { 
          neighbors.Add(new Label(i - 1, j, 0)); 
         } 
        } 
       } 
      } 
      if (j > 0) 
      { 
       if (this[i, j - 1].Gray == 1) 
       { 
        if (objectArray[i, j - 1] != 0) 
        { 
         neighbors.Add(new Label(i, j - 1, 0)); 
        } 
       } 
       if (i < colors.GetLength(1)) 
       { 
        if (this[i + 1, j - 1].Gray == 1) 
        { 
         if (objectArray[i + 1, j - 1] != 0) 
         { 
          neighbors.Add(new Label(i + 1, j - 1, 0)); 
         } 
        } 
       } 
      } 
      if (i < colors.GetLength(1)) 
      { 
       if (this[i + 1, j].Gray == 1) 
       { 
        if (objectArray[i + 1, j] != 0) 
        { 
         neighbors.Add(new Label(i + 1, j, 0)); 
        } 
       } 
       if (this[i + 1, j + 1].Gray == 1) 
       { 
        if (objectArray[i + 1, j + 1] != 0) 
        { 
         neighbors.Add(new Label(i + 1, j + 1, 0)); 
        } 
       } 
      } 
      if (j < colors.GetLength(0)) 
      { 
       if (this[i, j + 1].Gray == 1) 
       { 
        if (objectArray[i, j + 1] != 0) 
        { 
         neighbors.Add(new Label(i, j + 1, 0)); 
        } 
       } 
      } 

      if (neighbors.Count == 0) 
      { 
       objects++; 
       objectArray[i, j] = objects; 
       parents[i, j] = objects; 
      } 
      if (neighbors.Count > 0) 
      { 
       int smallestLabel = 10000; 
       foreach (Label x in neighbors) 
        if (objectArray[x.X, x.Y] < smallestLabel) 
         smallestLabel = objectArray[x.X, x.Y]; 

       foreach (Label x in neighbors) 
        parents[x.X, x.Y] = smallestLabel; 

       objectArray[i, j] = smallestLabel; 
       parents[i, j] = smallestLabel; 
      } 
     } 
    } 
    for (int i = 0; i < colors.GetLength(1); i++) for (int j = 0; j < colors.GetLength(0); j++) 
    { 
     if (this[i, j].Gray == 1) 
     { 
      if (objectArray[i, j] != 0) 
      { 
       objectArray[i, j] = parents[i, j]; 
       ColorWrap c = this[i, j]; 
       c.X = (float)objectArray[i, j]/objects; 
       c.Y = (float)objectArray[i, j]/objects; 
       c.Z = (float)objectArray[i, j]/objects; 
       this[i, j] = c; 
      } 
     } 
    } 
} 
+0

'라벨'이란 무엇입니까? –

+0

개체에 특정 회색 값을 지정하는 데 사용하는 개체를 구성하는 각 픽셀의 int 값입니다. 알고리즘은 연결된 픽셀의 이미지를 확인하고 발견 한 각 "객체"(연결된 각 픽셀의 "그룹", 각 장미이어야 함)에 레이블 값을 부여해야합니다 (예 : 왼쪽 상단의 장미를 구성하는 픽셀 레이블 값 1을 얻고, 왼쪽 하단의 장미 픽셀은 각각 레이블 값 2를 얻고 오른쪽 장미를 구성하는 픽셀은 각각 레이블 값 3을 얻습니다. 이 레이블 값을 사용하여이 픽셀에 새 회색 값을 제공합니다 (0120). – user1683526

+0

@ user1683526이 이진 이미지 또는 그레이 스케일입니까? –

답변

1

:

   if (this[i - 1, j + 1].Gray == 1) 
       { 
        if (objectArray[i - 1, j] != 0) 
        { 
         neighbors.Add(new Label(i - 1, j, 0)); 
        } 
       } 

세 가지 점에서 'J + 1'해야 다음 알고리즘입니다.

그래도 문제가 해결되지는 않습니다. 북서쪽에서 검은 색, 남동쪽에서 흰색 인 대각선 모서리를 만날 때 알고리즘에 문제가 있습니다.

왼쪽에서 오른쪽으로 이미지를 스캔하고 각 열을 위에서 아래로 행별로 스캔합니다. 8 개의 가능성있는 이웃을 확인하지만, 실제로 통과 한 이웃 목록에 픽셀을 추가 할 수 있습니다. 즉, 왼쪽 열의 세 픽셀과 현재 위치 위 픽셀의 픽셀 만 추가하면됩니다. '.'

  #######... 
      ######.... 
      #####..... 
      ####...... 
      ###O...... 
      ###....... 
      ##x....... 
      #xx....... 

('#'은, 검은 색, 흰색 할당하고, '다른 네 개의 인접하는 화소는 이제 이런 에지를 고려 0

의 부모 (또는 객체 인덱스) 것 x '는 흰색으로 부모는'O '로 현재 위치를 나타냅니다.)

검은 색 또는 할당되지 않은 인접한 타일 만 찾습니다. 네이버 목록은 비어 있습니다. 즉, 알고리즘은 새 오브젝트를 생성합니다. 논리적으로 아직 알려지지 않은 오브젝트의 남동쪽에 속해야합니다.

는 (당신은 백 트랙을 모든 이웃을 할당하는 새 그룹의 값을 픽셀,하지만 그건 하나 개의 픽셀을 수정하여. 또한, 즉 빈 그룹, 대응하는 픽셀이없는 개체를 만들 수 있다는 것을보십시오.)

어쨌든 당신의 접근 방식이 너무 복잡하다고 생각합니다. 또한 구성 요소 본체의 왼쪽 위 및 왼쪽 구석에 대해서는 설명하지 않습니다. 여분의 데이터 구조를 만들 필요가 없습니다. 그레이 스케일 이미지를 사용하는 경우 그림 자체에서 레이블을 지정할 수 있습니다. 이미지를 순수한 흑백으로 변환 한 후 모든 픽셀을 한 번 전달합니다. 픽셀이 흰색 인 경우 다음 객체에 해당하는 양의 회색 값이있는 그림을 거기에 대량으로 채우고 객체 수를 증가시킵니다. 그런 다음 모든 픽셀을 다시 전달하고 객체 ID 및 객체 수에 따라 회색 값을 조정합니다.

경고 : 그림 자체에서 모든 것을 할 수 있다고 말하면 레이블링이 254 개로 제한됩니다.

단점 : 코드를 약간 정리하고 싶을 수 있습니다. eqSetdisjointSet을 사용하지 않으므로 코드에서 제거하십시오. 두 배열 objectArrayparents은 같은 것을 위해 서로 나란히 사용됩니다. 그들을 하나로 합치십시오. 위의 8 가지 이웃 픽셀을 함수로 변환하여 (리팩터링하여) 잠재적 인 이웃 각각에 대해 하나의 호출로 리팩터링하여 위와 같이 인덱싱 오류를 방지하고 쉽게 읽을 수있게해야합니다.

+0

대단히 감사합니다. 홍수 채우기 알고리즘에 대해 살펴 보겠다. 그런 생각은하지 않았다. – user1683526

관련 문제