如何精準引流呢整站優(yōu)化多少錢
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請在顯著位置標明本文出處以及作者網(wǎng)名,未經(jīng)作者允許不得用于商業(yè)目的。
即將推出EmguCV的教程,請大家還稍作等待。
之前網(wǎng)友咨詢?nèi)绾潍@得圖像中圓形的半徑,其中有兩個十字作為標定,十字之間距離為100mm。如下圖:
說實在的,單靠VB.net很難獲得相關(guān)圓形信息,為了彌補這部分知識,下定決心學(xué)習(xí)了EmguCV。以下是具體代碼:https://blog.csdn.net/UruseiBest
Dim msrc As New Mat("C:\learnEmgucv\celiang.jpg", ImreadModes.Color)Dim mgray As New Mat()CvInvoke.CvtColor(msrc, mgray, ColorConversion.Bgr2Gray)Dim kernel As New Matkernel = CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1))Dim merode As New Mat ''這里使用了2次迭代CvInvoke.Dilate(mgray, merode, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing)CvInvoke.Threshold(merode, merode, 200, 255, ThresholdType.BinaryInv)'獲得所有輪廓 https://blog.csdn.net/UruseiBestDim contours As New VectorOfVectorOfPointDim hierarchy As New VectorOfRectCvInvoke.FindContours(merode, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple)Dim m2 As New Mat(merode.Size, DepthType.Cv8U, 1)m2.SetTo(New MCvScalar(0))'圓輪廓Dim contourCircle As VectorOfPoint'圓輪廓的周長Dim perimeter As Double'繪制輪廓 https://blog.csdn.net/UruseiBestFor i As Integer = 0 To contours.Size - 1Dim carea As VectorOfPoint = contours(i)'獲得輪廓面積Dim area As Double = CvInvoke.ContourArea(carea, False)'符合條件時,繪制輪廓,排除圓形,只保留十字線 '本圖中圓形面積為2449,直線面積為8,需要根據(jù)實際情況調(diào)整If area < 200 ThenCvInvoke.DrawContours(m2, contours, i, New MCvScalar(255), 0.4)Else'得到圓形,圖像中只有三個輪廓:2個交叉十字線段、1個圓形'這里簡化操作,否則在多個輪廓情況下,應(yīng)獲取最大面積的輪廓判斷為圓形contourCircle = contours(i)'獲取輪廓周長perimeter = CvInvoke.ArcLength(contourCircle, True)End IfNextImageBox1.Image = m2
'使用HoughLinesP方法檢測圖像中的直線,并將其繪制到圖像'因為本圖中十字線上的線段較短,所以這里閾值設(shè)置很小Dim lines As LineSegment2D() = CvInvoke.HoughLinesP(m2, 1, Math.PI / 180, 5, 5, 80)Dim m3 As New Mat(merode.Size, DepthType.Cv8U, 3)m3.SetTo(New MCvScalar(0, 0, 0))For Each line As LineSegment2D In linesCvInvoke.Line(m3, line.P1, line.P2, New MCvScalar(0, 255, 0), 2)NextImageBox2.Image = m3
'對直線進行分類,將其分為垂直和水平兩類:Dim verticalLines As New List(Of LineSegment2D)Dim horizontalLines As New List(Of LineSegment2D)'計算每條直線的傾斜角度來進行分類,'將傾斜角度在60 - 120度之間的直線劃分為垂直類,'將傾斜角度在30 - 150度之間的直線劃分為水平類。For Each line As LineSegment2D In linesDim angle As Double = Math.Atan2(line.P2.Y - line.P1.Y, line.P2.X - line.P1.X) * 180 / Math.PIIf angle < 0 Then angle += 180If angle > 60 AndAlso angle < 120 ThenverticalLines.Add(line)ElseIf angle > 150 OrElse angle < 30 ThenhorizontalLines.Add(line)End IfNext'對垂直和水平直線進行匹配,并計算十字中心點的位置:Dim intersections As New List(Of PointF)'得到兩個相交點 https://blog.csdn.net/UruseiBestFor Each verticalLine As LineSegment2D In verticalLinesFor Each horizontalLine As LineSegment2D In horizontalLines'基于圖像中兩條直線真實相交,'如果垂直線的中點X坐標在水平線兩端點X坐標之間'那么,這條垂直線段和這條水平線段相交Dim centerX As Single = (verticalLine.P1.X + verticalLine.P2.X) / 2If horizontalLine.P1.X < horizontalLine.P2.X ThenIf centerX > horizontalLine.P1.X And centerX < horizontalLine.P2.X ThenDim intersectionPoint As New PointF((horizontalLine.P1.X + horizontalLine.P2.X + verticalLine.P1.X + verticalLine.P2.X) / 4,(horizontalLine.P1.Y + horizontalLine.P2.Y + verticalLine.P1.Y + verticalLine.P2.Y) / 4)intersections.Add(intersectionPoint)End IfElseIf centerX > horizontalLine.P2.X And centerX < horizontalLine.P1.X ThenDim intersectionPoint As New PointF((horizontalLine.P1.X + horizontalLine.P2.X + verticalLine.P1.X + verticalLine.P2.X) / 4,(horizontalLine.P1.Y + horizontalLine.P2.Y + verticalLine.P1.Y + verticalLine.P2.Y) / 4)intersections.Add(intersectionPoint)End IfEnd IfNextNextIf intersections.Count <> 2 ThenMessageBox.Show("未能獲得兩個十字線的交叉點")Exit SubEnd IfCvInvoke.Line(msrc, PointFToPoint(intersections(0)), PointFToPoint(intersections(1)), New MCvScalar(0, 255, 0), 2)CvInvoke.Imshow("m3", msrc)
'計算兩個交點的距離Dim distance As Double = Math.Sqrt((intersections(0).X - intersections(1).X) ^ 2 +(intersections(0).Y - intersections(1).Y) ^ 2)'實際中兩交點距離為100毫米,計算相應(yīng)比例Dim proportion As Double = 100 / distance'以下是基于最小外接圓來計算實際圓半徑Dim cf As CircleFcf = CvInvoke.MinEnclosingCircle(contourCircle)'獲得外接圓形 https://blog.csdn.net/UruseiBestCvInvoke.Circle(msrc, New Point(CInt(cf.Center.X), CInt(cf.Center.Y)), cf.Radius, New MCvScalar(0, 0, 255), 2)CvInvoke.Imshow("m4", msrc)
'實際圓半徑Dim realradius1 As Doublerealradius1 = proportion * cf.Radius'以下是基于輪廓周長來計算實際圓半徑'實際圓周長Dim realperimeter As Double = perimeter * proportion'圖像中的圓半徑 https://blog.csdn.net/UruseiBestDim radius As Doubleradius = (perimeter / Math.PI) / 2'實際圓半徑Dim realradius2 As Doublerealradius2 = proportion * radiusMessageBox.Show("最小外接圓來計算實際圓半徑:" & realradius1 & ControlChars.CrLf &"基于輪廓周長來計算實際圓半徑:" & realradius2)
這個網(wǎng)友當時提出來問題的時候,我還沒有辦法解決,不過經(jīng)過不斷學(xué)習(xí),目前已經(jīng)學(xué)習(xí)了不少相關(guān)知識,至少可以獲得圓半徑了,還是略微感到欣慰。?
關(guān)于EmguCV的知識,下一步整理出來。
由于.net平臺下C#和vb.NET很相似,本文也可以為C#愛好者提供參考。
學(xué)習(xí)更多vb.net知識,請參看vb.net 教程 目錄