在一幅二值化后的图像里,怎样找出所有的斑?假如斑归一化为黑色,其他为白色,那么一行一行去找,从左到右,从上到下,当发现有黑色,就开始寻找他8个邻域有无黑色,有,继续,一直找出所有黑色,这就是一个斑(blob),然后把它存入list序列里,让他全为白色,这个斑就算搞定,最后到图象结束,所有斑就全存入list序列里了,图像也全部染成白色,这就是找斑的核心而又简单的算法。c#找斑染色算法如下(排除掉小于10个像素的斑):(为什么会喜欢染色算法这个名称,因为我爷爷辈是染布的,家里还有旧物染缸,小时候,做迷藏会藏里边)
public void 染色算法(ref List<List<Point>> llp, ref byte[] tempbuffer8, int W, int H)//tempbuffer8会被改变
{
int areathreshold = Convert.ToInt32(textBoxarea.Text);//c
//1,找到所有斑点,存入llp
int[] xNum = new int[] { 1, 1, 0, -1, -1, -1, 0, 1 };
int[] yNum = new int[] { 0, 1, 1, 1, 0, -1, -1, -1 };
long yy = 0, xx = 0;
//開始尋找斑點,使用堆棧染色法
for (int m = 0; m < H; m++)
for (int n = 0; n < W; n++)//*****
{
if (tempbuffer8[m * W + n] == 0)
{
List<Point> lp = new List<Point>();
Point p = new Point();
p.X = n;
p.Y = m;
//找到起点并填充原始图形
Stack<Point> s = new Stack<Point>();
tempbuffer8[p.Y * W + p.X] = 240;//如果是斑點已經全部染成240白,not250白
s.Push(p);
lp.Add(p);
//使用堆栈的方法染色
do
{
//Point pt1 = s.ElementAt(0);
Point pt1 = s.Peek();
s.Pop();
for (int k = 0; k < 8; k++)
{
yy = pt1.Y + yNum[k];
xx = pt1.X + xNum[k];
long instead = (yy * W + xx);
if (tempbuffer8[instead] == 0)
{
tempbuffer8[instead] = 240;
Point pt = new Point((int)xx, (int)yy);
s.Push(pt);
lp.Add(pt);
}
}
} while (s.Count != 0);
//llp中存入面积大於10的斑點,請使用變量
if (lp.Count >= areathreshold)
{
llp.Add(lp);
}
}
}
}
效果图:
(黄色圈定为斑,显然孔未识别,考虑使用什么办法?不用OpenCV的话,想一想。)
当你看过opencv之后,你会发现这个算法是有缺点的,即斑中孔(hole)是没有考虑到的。当你发现不如别人时,其实打击是很大的,但是从原创来看,灰暗的心态就会消失,因为你已经做到了,而且并不逊色,与斑(blob)共生的还有轮廓(contour)的寻找,也存在这种情况,回头很快就会见面。
你会不会按opencv的方法改进?够用就好,而且当你明白斑与孔的概念之后,仍然使用反色和染色的方法,孔(hole)就会变成斑,问题就迎刃而解。
待续(慢慢来!...........)每天一点小改变☺
我的邮箱liuganggang_1978@163.com;734523623@qq.com