Fig.1 GUI介面
Fig.2 用以進行圓形辨識的圖片
Video 1 圓形辨識程式執行,辨識簡易圖形
Video 2 圓形辨識程式執行,辨識實際工業元件
先編輯GUI(Graphical User Interface)介面,需要的元件皆是從「工具箱」內選取,此影像處理程式所需要的元件如下所示:
標籤(Label)x3
- Label1: 設定Text為BgrPic,用來表示彩色圖片。
- Label2: 設定Text為GrayPic,用來表示灰階圖片。
- Label3: 設定Text為The Circle which is closest to the Image Center:,用來表示最靠近圖中心的圓心的座標,將顯示於Label3下方的textbox中。
影像盒子(PictureBox)x2
- PictureBox1: 設定name為OriginPic,表示原始圖片;設定Size為267, 200,SizeMode為StretchImage。
- PictureBox2: 設定name為ModifiedPic,表示用來計算的圖片;設定Size為267, 200,SizeMode為StretchImage。
此篇介紹的圓辨識方法,是先將彩色圖(Bgr Image)轉換成灰階圖(Gray Image),然後在灰階圖上進行圓的辨識。
按鈕(Button)x2
- Button1: 設定Text為Browse,Size為100, 40,Font為12pt。
- Button2: 設定Text為Circles,Size為100, 40,Font為12pt。
資料表格顯示窗(DataGridView)x1
- DataGridView1,設定size為440,180。
文字框(TextBox)x1
- TextBox1,設定Font=12pt,ReadOnly=True。
開啟檔案對話框(OpenFileDialog)x1
- OpenFileDialog1: 直接放入,會顯示在GUI介面之外。
-----------------------------------------------------------------------------------------------------------------
程式碼都是針對按鈕(Button)撰寫,從Button1-->Button2依序點開來撰寫:
Imports Emgu.CV
Imports Emgu.CV.Structure
Imports Emgu.CV.CvEnum
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
OpenFileDialog1.InitialDirectory = "D"
OpenFileDialog1.Title = "Open Iamge"
OpenFileDialog1.Filter = "Gamber |*.bmp; *.jpg; *.gif; *.jpeg"
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
OriginPic.Image = Image.FromFile(OpenFileDialog1.FileName)
'將開啟的圖片顯示在OriginPic上
'將開啟的圖片顯示在OriginPic上
Exit Sub
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim imgOriginal As New Image(Of Bgr, Byte)(OriginPic.Image)
Dim imgProcessed As Image(Of Gray, Byte)
imgProcessed = imgOriginal.InRange(New Bgr(0, 0, 0), New Bgr(10, 10, 10))
imgProcessed = imgProcessed.SmoothGaussian(9)
Dim circles As CircleF() = imgProcessed.HoughCircles(New Gray(100), New Gray(50), 2, 15, 27, 30)(0)
'找圓的方法是用HoughCircles(霍夫找圓),這個方法只能在灰階位元圖(Gray,Byte Image)上執行。
'所以要先將圖檔轉為彩色位元圖,再將彩色位元圖轉為灰階位元圖,才可以進行霍夫找圓。
'其中,在彩色位元圖轉為灰階位元圖時,要先用Inrange抓出畫面中圓的色彩。
'譬如此範例要找的圓為黑色,因此設InRange(New Bgr(0, 0, 0), New Bgr(10, 10, 10))。
'程式碼到目前為止,已找出圓了,下方程式碼則是對找出的圓進行標示。
Dim d As Double
Dim dtable As New DataTable
dtable.Columns.Add("nn")
dtable.Columns.Add("dd", System.Type.GetType("System.Int32"))
dtable.Columns.Add("XX")
dtable.Columns.Add("YY")
Dim nCircles = 0
For Each CircleF In circles
nCircles = nCircles + 1
CvInvoke.Circle(imgOriginal, New Point(CInt(CircleF.Center.X), CInt(CircleF.Center.Y)), 3, New MCvScalar(0, 255, 0), -1, LineType.AntiAlias, 0) '在imgOriginal圖上標示圓心
imgOriginal.Draw(CircleF, New Bgr(Color.Red), 3) '在imgOriginal圖上標示圓弧
imgOriginal.Draw(nCircles.ToString, New Point(CircleF.Center.X, CircleF.Center.Y - 30), FontFace.HersheySimplex, 1.5, New Bgr(Color.Red), 3, LineType.AntiAlias, False)
'在imgOriginal圖上標示圓編號
imgProcessed.Draw(CircleF, New Gray(100), 3) '在imgProcessed圖上標示圓弧
d = ((CircleF.Center.X - 606) ^ 2 + (CircleF.Center.Y - 455) ^ 2) ^ 0.5 '計算與圖片中心的距離,圖片大小為1211x909
dtable.Rows.Add(nCircles.ToString(), CInt(d), CircleF.Center.X, CircleF.Center.Y) '將圓的編號、與中心的距離、X座標、Y座標 加入dtable表格
Next
OriginPic.Image = imgOriginal.ToBitmap
ModifiedPic.Image = imgProcessed.ToBitmap
dtable.DefaultView.Sort = "dd ASC" '表格排序,dd欄位由小到大排序。注意dd欄位要設成整數或浮點數,不能設為字串。
dtable = dtable.DefaultView.ToTable '排序完寫回dtable表格
DataGridView1.DataSource = dtable '將dtable表格顯示在DataGridView1
TextBox1.Text = "n =" + dtable.Rows(0)(0) + ",d =" + dtable.Rows(0)(1).ToString + ",X = " + dtable.Rows(0)(2) + ",Y =" + dtable.Rows(0)(3)
'將dtable的第一列,也就是d數值最小的那列(離圖片中心最近的圓心),顯示在TextBox1。
End Sub
End Class
-----------------------------------------------------------------------------------------------------------------
重點函數解說:
Dim circles As CircleF() = imgProcessed.HoughCircles(Canny threshold, accumulator threshold, size of image / this param = "accumulator resolution“, min distance in pixels between the centers of the detected circles, min radius of detected circle, max radius of detected circle)(get circles from the first channel)
Dim circles As CircleF() = imgProcessed.HoughCircles(影像邊緣閥值, 影像累積閥值, 解析度參數, 每個偵測的圓之間的距離, 偵測的圓的最小半徑, 偵測的圓的最大半徑)(0)
解析度參數說明:原影像Size/解析度參數=用來找圓的影像Size,所以解析度參數越大,找圓的影像Size越小,找圓的速度就越快,但越不準確。
eg.
Dim circles As CircleF() = imgProcessed.HoughCircles(New Gray(100), New Gray(50), 2, 15, 27, 30)(0)
'將資料放入表格中
重點函數解說:
- HoughCircles用法
Dim circles As CircleF() = imgProcessed.HoughCircles(Canny threshold, accumulator threshold, size of image / this param = "accumulator resolution“, min distance in pixels between the centers of the detected circles, min radius of detected circle, max radius of detected circle)(get circles from the first channel)
Dim circles As CircleF() = imgProcessed.HoughCircles(影像邊緣閥值, 影像累積閥值, 解析度參數, 每個偵測的圓之間的距離, 偵測的圓的最小半徑, 偵測的圓的最大半徑)(0)
解析度參數說明:原影像Size/解析度參數=用來找圓的影像Size,所以解析度參數越大,找圓的影像Size越小,找圓的速度就越快,但越不準確。
eg.
Dim circles As CircleF() = imgProcessed.HoughCircles(New Gray(100), New Gray(50), 2, 15, 27, 30)(0)
- Datatalbe用法
Dim dtable As New DataTable '建立表格
dtable.Columns.Add("nn")
dtable.Columns.Add("dd", System.Type.GetType("System.Int32"))
dtable.Columns.Add("XX")
dtable.Columns.Add("YY")
'建立每個欄位,並附上欄位名字,設定欄位"dd"資料格式為Int32
dtable.Rows.Add(nCircles.ToString(), CInt(d), CircleF.Center.X, CircleF.Center.Y)'建立每個欄位,並附上欄位名字,設定欄位"dd"資料格式為Int32
'將資料放入表格中
dtable.DefaultView.Sort = "dd ASC
dtable = dtable.DefaultView.ToTable
'資料排序,"dd"欄位設成int32才能依照數字大小排序
DataGridView1.DataSource = dtable
'將資料顯示於DataGridView1上
Datatable.Rows表示的位置如下圖所示:
'將資料顯示於DataGridView1上
Datatable.Rows表示的位置如下圖所示:
Fig.3 Datatable.Rows的位置標示
---------------------------------------------------------------------------------------------------------------------
辨識實際工業元件,程式碼有部分需要修改,以紅色註記:
Imports Emgu.CV
Imports Emgu.CV.Structure
Imports Emgu.CV.CvEnum
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
OpenFileDialog1.InitialDirectory = "D"
OpenFileDialog1.Title = "Open Iamge"
OpenFileDialog1.Filter = "Gamber |*.bmp; *.jpg; *.gif; *.jpeg"
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
OriginPic.Image = Image.FromFile(OpenFileDialog1.FileName) '將開啟的圖片顯示在OriginPic上
Exit Sub
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim imgOriginal As New Image(Of Bgr, Byte)(OriginPic.Image)
Dim imgProcessed As Image(Of Gray, Byte)
imgProcessed = imgOriginal.InRange(New Bgr(10, 10, 20), New Bgr(90, 100, 150))
imgProcessed = imgProcessed.SmoothGaussian(9)
Dim circles As CircleF() = imgProcessed.HoughCircles(New Gray(100), New Gray(50), 2, 15, 65, 80)(0)
'找圓的方法是用HoughCircles(霍夫找圓),這個方法只能在灰階位元圖(Gray,Byte Image)上執行。
'所以要先將圖檔轉為彩色位元圖,再將彩色位元圖轉為灰階位元圖,才可以進行霍夫找圓。
'其中,在彩色位元圖轉為灰階位元圖時,要先用Inrange抓出畫面中圓的色彩,譬如此範例要找的圓為黑色,因此設InRange(New Bgr(0, 0, 0), New Bgr(10, 10, 10))。
'程式碼到目前為止,已找出圓了,下方程式碼則是對找出的圓進行標示。
Dim d As Double
Dim dtable As New DataTable
dtable.Columns.Add("nn")
dtable.Columns.Add("dd", System.Type.GetType("System.Int32"))
dtable.Columns.Add("XX")
dtable.Columns.Add("YY")
Dim nCircles = 0
For Each CircleF In circles
nCircles = nCircles + 1
CvInvoke.Circle(imgOriginal, New Point(CInt(CircleF.Center.X), CInt(CircleF.Center.Y)), 3, New MCvScalar(0, 255, 0), -1, LineType.AntiAlias, 0) '在imgOriginal圖上標示圓心
imgOriginal.Draw(CircleF, New Bgr(Color.Red), 3) '在imgOriginal圖上標示圓弧
imgOriginal.Draw(nCircles.ToString, New Point(CircleF.Center.X, CircleF.Center.Y - 30), FontFace.HersheySimplex, 3, New Bgr(Color.Red), 3, LineType.AntiAlias, False)
'在imgOriginal圖上標示圓編號
imgProcessed.Draw(CircleF, New Gray(100), 3) '在imgProcessed圖上標示圓弧
d = ((CircleF.Center.X - 1024) ^ 2 + (CircleF.Center.Y - 768) ^ 2) ^ 0.5 '計算與圖片中心的距離,圖片大小為2048x1536
dtable.Rows.Add(nCircles.ToString(), CInt(d), CircleF.Center.X, CircleF.Center.Y) '將圓的編號、與中心的距離、X座標、Y座標 加入dtable表格
Next
OriginPic.Image = imgOriginal.ToBitmap
ModifiedPic.Image = imgProcessed.ToBitmap
dtable.DefaultView.Sort = "dd ASC" '表格排序,dd欄位由小到大排序。注意dd欄位要設成整數或浮點數,不能設為字串。
dtable = dtable.DefaultView.ToTable '排序完寫回dtable表格
DataGridView1.DataSource = dtable '將dtable表格顯示在DataGridView1
TextBox1.Text = "n =" + dtable.Rows(0)(0) + ",d =" + dtable.Rows(0)(1).ToString + ",X = " + dtable.Rows(0)(2) + ",Y =" + dtable.Rows(0)(3)
'將dtable的第一列,也就是d數值最小的那列(離圖片中心最近的圓心),顯示在TextBox1。
End Sub
End Class

沒有留言:
張貼留言