연결된 구성 요소 레이블링 알고리즘을 작성하려고했지만 원하는 결과를 얻지 못했습니다. 지금은 3 개의 장미가 겹쳐져 있지 않은 이미지가 있고 각각의 장미에 고유 한 회색 값을 붙이고 싶습니다. 라벨링 알고리즘을 적용하기 전에 배경을 제거하고 장미 만 유지하기 위해 임계 값을 사용합니다. 장미는 회색 값 1 (완전히 흰색 임)을 얻고 배경은 회색 값 0 (검정)을 얻습니다. 다음은이 모양의 이미지입니다. 연결된 구성 요소 레이블 지정 알고리즘에 문제가 있음
이렇게 한 후 라벨 알고리즘을 적용합니다. 그것은 주어진 레이블에 따라 장미에 세 가지 다른 회색 값을 부여해야합니다. 그러나 알고리즘은 첫 번째 두 장미 위에이 이상한 종류의 그라디언트 패턴을 만듭니다. 마지막 하나는 단일 회색 값인 것처럼 보입니다. 이미지는 다음과 같습니다.
알고리즘이 복잡해 보이지만 실제로는 매우 간단합니다. 먼저 열과 행을 반복하고 배경이 아닌 각 픽셀에 대해 이웃이 이미 레이블링되어 있는지 확인합니다 (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;
}
}
}
}
'라벨'이란 무엇입니까? –
개체에 특정 회색 값을 지정하는 데 사용하는 개체를 구성하는 각 픽셀의 int 값입니다. 알고리즘은 연결된 픽셀의 이미지를 확인하고 발견 한 각 "객체"(연결된 각 픽셀의 "그룹", 각 장미이어야 함)에 레이블 값을 부여해야합니다 (예 : 왼쪽 상단의 장미를 구성하는 픽셀 레이블 값 1을 얻고, 왼쪽 하단의 장미 픽셀은 각각 레이블 값 2를 얻고 오른쪽 장미를 구성하는 픽셀은 각각 레이블 값 3을 얻습니다. 이 레이블 값을 사용하여이 픽셀에 새 회색 값을 제공합니다 (0120). – user1683526
@ user1683526이 이진 이미지 또는 그레이 스케일입니까? –