-歡迎轉載,請務必注明出處。-
很長時間沒寫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; }
本人才疏學淺,歡迎朋友們共同討論。