Hi , I am trying to separate the shapes from an binary image (the white pixels) using connected component labeling algorithm,however I can’t seem to figure out what is going wrong. Any help is appreciated.
Image link :
Before:https://drive.google.com/file/d/1YHHt7uGM0Nz2LIiDDy-rPQ4pMaxFeSuB/view
After:https://drive.google.com/file/d/1wwU-xajrIKoYUW6107rR3rfECstKpS36/view
//first pass does the labeling
public static Texture2D FirstPass(Texture2D source)
{
//1-D array of color from source
Color[] color = source.GetPixels(0);
int width = source.width;
Texture2D result = new Texture2D(source.width, source.height);
//current label number
int currRegion = 0;
Dictionary<int, NodeLabel> labels = new Dictionary<int, NodeLabel>();
Color top = Color.green, left = Color.green;
//neighbouring top,left and current label respectively
NodeLabel t_A = new NodeLabel(), l_B = new NodeLabel(), currLabel = new NodeLabel();
//index of neighbour in color array
int topIndex = 0, leftIndex = 0;
for (int i = 0; i < color.Length; i++)
{
//current pixel is white
if (color *== Color.white)*
{
topIndex = i - width;
top = i >= width ? color[topIndex] : Color.green;
leftIndex = i - 1;
if ( ((leftIndex + 1) % width) == 0 || i == 0)
left = Color.green;
else
left = color[leftIndex];
if (top == Color.black && left == Color.black)
{
currRegion++;
currLabel = new NodeLabel(currRegion, i);
labels.Add(i, currLabel);
}
else
{
t_A = top == Color.white ? labels[topIndex] : null;
l_B = left == Color.white ? labels[leftIndex] : null;
currLabel = new NodeLabel(currRegion, i);
labels.Add(i, currLabel);
if (t_A != null && l_B != null)
{
NodeLabel lowestRegion;
lowestRegion = t_A.region < l_B.region ? t_A : l_B;
currLabel.region = lowestRegion.region;
if (t_A.region != l_B.region)
{
Debug.Log(“set parents”);
t_A.MergeRoot(l_B);
}
labels[currLabel.colorIndex] = currLabel;
labels[t_A.colorIndex] = t_A;
labels[l_B.colorIndex] = l_B;
}
else if (t_A != null)
{
currLabel.region = t_A.region;
labels[currLabel.colorIndex] = currLabel;
}
else if (l_B != null)
{
currLabel.region = l_B.region;
labels[currLabel.colorIndex] = currLabel;
}
else
{
currRegion++;
currLabel = new NodeLabel(currRegion, i);
labels[currLabel.colorIndex] = currLabel;
}
}
}
}
color = SecondPass(labels, color);
result.SetPixels(color);
return result;
}
//second pass sorts the labels and color each label uniquely
public static Color[] SecondPass(Dictionary<int, NodeLabel> labels, Color[] c)
{
Color color = Color.cyan;
Dictionary<int, Color> regionKeys = new Dictionary<int, Color>();
foreach (NodeLabel item in labels.Values)
{
item.region = item.GetRootParent().region;
if (regionKeys.ContainsKey(item.region))
color = regionKeys[item.region];
else
{
while(regionKeys.ContainsValue(color))
{
color = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value, 1);
}
regionKeys.Add(item.region, color);
}
c[item.colorIndex] = color;
}
foreach (var item in regionKeys.Keys)
{
Debug.Log(“region value:” + item.ToString());
}
Debug.Log(“Region count:” + regionKeys.Keys.Count.ToString());
return c;
}
----------
//here is the node label class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NodeLabel
{
public int region = 0;
public NodeLabel parent;
public int colorIndex;
public Color color = Color.white;
public NodeLabel() { }
public NodeLabel(int region, int colorIndex )
{
this.region = region;
this.colorIndex = colorIndex;
parent = this;
}
public void MergeRoot(NodeLabel label)
{
- NodeLabel myRoot = GetRootParent();*
-
label = label.GetRootParent();*
-
if(myRoot.region < label.region) *
-
label.parent = myRoot;*
-
else*
-
myRoot.parent = label;*
}
public NodeLabel GetRootParent()
{
NodeLabel curr = this;
NodeLabel root = this.parent;
while(curr != root)
{
curr = parent;
root = this.parent;
}
-
parent = curr;*
return curr;
}
public void MergeToRoot()
{
NodeLabel root = GetRootParent();
NodeLabel curr = this;
while (curr != this.parent)
{
curr.region = root.region;
curr = parent;
}
}
}