-欢迎转载,请务必注明出处。-
很长时间没写BLOG了。最近公司在搞个项目,本来要请专业的机器视觉设计的公司来做的,但无耐报价太高。没有7、8万做不下来,于是自己折腾。
以下是正文:
一、项目描述:
产品组装完后放在托盘中,约200个一张托盘。产品的放置有方向性要求,现在搞人工检测,有漏检现象。现需要做一套装置对方向进行识别,如果有产品放置反了给出报警即可。
二、需求分析:
1.硬件:(1)采集&处理:光源 + 相机 + 采集卡 + IO卡 + 主机
(2)执行(托盘搬运):PLC + 电磁阀 + 气缸 + 机构件
注:硬件上的实现本文不作介绍。
2.软件:c#实现,步骤详见图像分析。
三、图像分析:
由于托盘面积较大,现用4个产品进行手工测试。
1.基本思路: (1)建立样本->(2)二值化->(3)样本特征采集->(4)采集图像->(5)二值化->(6)提取特征->(7)与样本特征比对(8)给出结果
2.详细说明:
(1)建立样本->(2)二值化->(3)样本特征采集
(4)采集图像->(5)二值化->(6)提取特征
(7)与样本特征比对(8)给出结果。
3.其它的都比较简单,主要是二值图转换一定要有效,在这里给出二值图的转换方法,可以直接使用。调节亮度值即可获取不同的二值图:
/// <summary> /// 根据亮度阀值获取二值图 /// </summary> /// <param name="img"></param> /// <param name="stdBrightness">亮度阀值</param> /// <returns></returns> public static Bitmap BitmapTo1Bpp(Bitmap img,double stdBrightness) { int w = img.Width; int h = img.Height; Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed); BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed); byte[] scan = new byte[(w + 7) / 8]; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (x % 8 == 0) scan[x / 8] = 0; Color c = img.GetPixel(x, y); if (c.GetBrightness() >= stdBrightness) scan[x / 8] |= (byte)(0x80 >> (x % 8)); } Marshal.Copy(scan, 0, (IntPtr)((long)data.Scan0 + data.Stride * y), scan.Length); } bmp.UnlockBits(data); return bmp; }
本人才疏学浅,欢迎朋友们共同讨论。