整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          教你用OpenCV 和 Python實現(xiàn)圓物檢測

          于python使用OpenCV實現(xiàn)在一張圖片中檢測出圓形,并且根據(jù)圓檢測結(jié)果信息,繪制 標(biāo)記出圓的邊界和圓心。

          1 HoughCircles 霍夫圓檢測

          在Opencv中使用HoughCircles函數(shù)實現(xiàn)圓的檢測,具體函數(shù)參數(shù)如下:

          • image: 輸入圖像,8位灰度單通道圖像
          • method: 檢測圓的方法,目前OpenCV中有HOUGH_GRADIENTHOUGH_GRADIENT_ALT兩種方法。
          • dp: 檢測圓心的累加器圖像的分辨率與輸入圖像之比的倒數(shù),如果dp= 1時,累加器和輸入圖像具有相同的分辨率。如果dp=2,累加器輸入圖像便有輸入圖像一半那么大的寬度和高度。減少圖像的分辨率(寬高變小)是為了減少計算量,一般默認為1就好,保持原有圖像精度。
          • minDist: 檢測到的兩個圓心之間的最小距離。如果參數(shù)太小,除了真實的一個圓圈之外,可能錯誤地檢測到多個相鄰的圓圈。如果太大,可能會遺漏一些圓圈。
          • circles: 檢測到的圓的信息輸出向量(x,y,r),分別代表檢測到圓的中心坐標(biāo)和圓半徑。
          • param1: Canny 邊緣檢測的高閾值,低閾值被自動置為高閾值的一半,默認為 100。也就是說檢測圖像中像素點的值大于param1是會檢測為邊緣。
          • param2: 表示在檢測階段圓心的累加器閾值。它越小的話,會誤檢測到更多根本不存在的小圓,而越大,能通過檢測的圓就更加接近完美的圓形了。
          • minRadius: 表示圖像中能檢測到最小圓的半徑的值。
          • maxRadius: 表示圖像中檢測到的圓的最大半徑的值。

          參數(shù)設(shè)置總結(jié)

          • param2值的設(shè)置根據(jù)要檢測圖像中圓的大小進行設(shè)置,minRadius最小圓半徑和maxRadius最大圓半徑可以輔助我們更好選擇圓,如果沒有特殊需要就都默認為0。minDist可以幫助我們篩選掉檢測相近的圓。
          • 霍夫圓檢測的原理:第一步通過Canny邊緣檢測算法檢測邊緣,發(fā)現(xiàn)可能的圓心,然后再計算邊緣像素點到圓心的距離估計圓的半徑。


          2 HoughCircles 霍夫圓檢測代碼實現(xiàn)

          實現(xiàn)霍夫圓檢測的實現(xiàn)代碼非常簡單,首先使用cv2.cvtColor函數(shù)將要檢測的圖像轉(zhuǎn)換為灰度圖像,然后調(diào)用cv2.HoughCircles霍夫圓檢測函數(shù)進行檢測,檢測返回所有圓的中心坐標(biāo)和半徑信息向量circles(x,y,r)

          注意: 霍夫圓檢測對噪聲比較敏感,所以進行霍夫圓檢測的之前可以先進行中值濾波cv2.medianBlur

          def circle_detect(image):
              # 灰度化
              gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
              # 輸出圖像大小,方便根據(jù)圖像大小調(diào)節(jié)minRadius和maxRadius
              print(image.shape)
              # 進行中值濾波
              img = cv2.medianBlur(gray, 5)
          
              # 霍夫變換圓檢測
              circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=5, maxRadius=100)
              for circle in circles[0]:
                  # 圓的基本信息
                  print(circle[2])
                  # 坐標(biāo)行列-圓心坐標(biāo)
                  x = int(circle[0])
                  y = int(circle[1])
                  # 半徑
                  r = int(circle[2])
                  # 在原圖用指定顏色標(biāo)記出圓的邊界
                  cv2.circle(image, (x, y), r, (0, 0, 255), 3)
                  # 畫出圓的圓心
                  cv2.circle(image, (x, y),5, (0, 255, 0), -1)
          
              cv2.imshow("image",image)
          
          img = cv2.imread(r'D:\yolov5-5.0\data\images\1.jpg')
          circle_detect(image=img)
          
          cv2.waitKey(0)
          

          最后再借助OpenCV中的畫圓函數(shù)cv2.circle,cv2.Circle函數(shù)參數(shù)

          • img: 要在其上繪制圓的輸入圖像
          • center: 繪制圓的中心坐標(biāo)(x,y),未設(shè)置shift參數(shù)時,默認為整數(shù)int類型。
          • radius: 繪制圓的半徑,未設(shè)置shift參數(shù)時,默認為整數(shù)int類型
          • color: 繪制圓的邊界線的顏色,OpenCV讀取圖像后,圖像格式為BGR,即【0,255,255】表示用紅色繪制圓的邊緣。
          • thickness:圓的邊界線的粗細像素值。值為負(-1)時繪制實心圓。
          • lineType:可選參數(shù),線的類型:虛線、實線
          • shift:可選參數(shù),圓心坐標(biāo)點和半徑值的小數(shù)點位數(shù)。

          3 檢測效果

          通過合理的控制minDistminRadiusmaxRadiusparam2這四個參數(shù)的值,最終的檢測效果如下圖:

          參考資料:
          https://www.cnblogs.com/april0315/p/13657682.html
          https://www.cnblogs.com/bjxqmy/p/12333022.ht

          后臺回復(fù):項目實戰(zhàn),即可獲取代碼下載使用。

          往期精彩:教你用OpenCV 和 Python給證件照換底色(藍底 <->紅底->白底) &&教你用OpenCV和Python實現(xiàn)手掌檢測和手掌計數(shù)

          制圓形和圓弧都使用arc()方法:

          Arc(x, y, r, startAngle, endAngle, antiClockwise)

          Arc()方法是從(x,y)位置畫出半徑為r的圓形;

          startAngle及endAngle決定圓弧的起點角度與終點角度; startAngle: 起點是X軸方向, 即3點鐘方向。

          antiClockwise參數(shù)決定是否已逆時針方向繪圖,逆時針為true,順時針為false。


          在canvas中所有涉及角度的坐標(biāo)系有兩點注意的:

          0弧度的方向是正右方向。

          弧度的順時針和逆時針:


          角度與弧度轉(zhuǎn)公式

          角度轉(zhuǎn)弧度 π/180×角度

          弧度變角度 180/π×弧度


          將角度轉(zhuǎn)換為弧度,計算公式可以參考下面的公式:

          radians = degrees * Math.PI/180

          degrees 角度

          radians 弧度

          圓的弧度(360):360 * Math.PI/180 = Math.PI * 2 = 6.28

          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="utf-8">
          <title>繪制圓</title>
          <script type="text/javascript">
          function drawCircle(){
          var canvas = document.getElementById('myCanvas');
          var ctx = canvas.getContext('2d');
          //開始繪圖--圓
          ctx.strokeStyle="#336600"; //設(shè)定邊框顏色
          ctx.lineWidth=10; //設(shè)定線條寬度 10px
          ctx.fillStyle="#FF0000"; //設(shè)定填充顏色
          ctx.beginPath(); //路徑開始
          ctx.arc(100,100,50,0,Math.PI*2,true); //起始點(100,100)半徑50的圓
          ctx.closePath(); //關(guān)閉路徑
          ctx.fill(); //繪出填滿圖形
          ctx.stroke(); //繪出邊框
          }
          </script>
          <!--style標(biāo)記內(nèi)是CSS語法-->
          <style type="text/css">
          Canvas { border: 1px solid black; } //將框線設(shè)為1px
          </style>
          </head>
          <body>
          <input type="button" value=" 畫 圓 " onclick="drawCircle();"><br />
          <canvas id="myCanvas" width="400" height="200"></canvas>
          </body>
          </html>

          繪制圓弧

          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="UTF-8" />
          <title>繪制圓弧</title>
          <style type="text/css">
          canvas{
          border: 1px solid #000;
          }
          </style>
          </head>
          <body>
          <canvas width="600" height="400"></canvas>
          </body>
          <script type="text/javascript">
          var canvas = document.querySelector("canvas")
          var ctx = canvas.getContext("2d");
          ctx.beginPath(); //開始繪制路徑
          // ctx.arc(100, 100, 60, 0, 6.28, false);
          // ctx.arc(100, 100, 60, 0, -6.28, true);
          ctx.arc(100, 100, 60, 0, Math.PI * 2, false);
          ctx.stroke(); //顯示路徑線
          ctx.fillStyle = "pink";   //設(shè)置填充顏色
          ctx.fill(); //填充顏色
          </script>
          </html>


          繪制笑臉


          在前端開發(fā)中經(jīng)常會用到很多的簡易圖形,例如三角形,箭頭,圓形等。有很多人一開始會想著用小的圖片實現(xiàn),不過這樣會增加頁面請求次數(shù),延緩頁面加載效果。

          在CSS中有個border屬性,它完全可以達到制作各種簡易圖形的效果,今天我們就一起來看看吧。

          文章中的代碼都已經(jīng)放在了github上,感興趣的同學(xué)自取。

          https://github.com/zhouxiongking/article-pages/blob/master/articles/border/border.html

          CSS

          border講解

          在制作各種簡易圖形之前,我們先來看看border屬性的使用。

          border是一個復(fù)合屬性。

          • border-width表示邊框?qū)挾取?/p>

          • border-style表示邊框樣式,設(shè)置實線,虛線,點狀等。

          • border-color表示邊框顏色,還可以設(shè)置transparent,表示透明。

          border又分為上下左右四個方向,每個方向都占據(jù)各自的空間,不會出現(xiàn)重疊的地方,尤其是在四個方向的邊框都設(shè)置的情況下,在四個角處也不會出現(xiàn)重疊。

          我們來看個最簡單的例子,在四個方向上都設(shè)置邊框,賦予不同的顏色。

          圖片1

          通過上面的圖片1可以看出,四個角處是分離,沒有重合的。

          梯形

          首先我們來看看梯形的效果圖。

          梯形效果圖

          我們再來分析下梯形是如何實現(xiàn)的。

          • 因為我們完全是通過border設(shè)置,所以這個div的高度應(yīng)該為0。

          • 梯形的左右兩個腰,恰好如同border在角的銜接處,然后將兩側(cè)的border-style設(shè)置為transparent。

          因此我們可以得到以下的CSS代碼。

          梯形的CSS代碼

          修改border-left和border-right的寬度值,可以改變梯形的形狀。

          三角形

          三角形也分為上下左右四個方向,我們首先來看看總體的形狀。

          三角形

          然后我們也來分析下如何實現(xiàn)這個效果,以下三角形為例。

          • 因為是呈現(xiàn)三角形的形狀,剛好契合border在角落的銜接處,因此高度和寬度都應(yīng)該為0。

          • 下三角形是上部有區(qū)域,所以要設(shè)置border-top。

          • border-left和border-right兩個方向都要設(shè)置寬度,然后設(shè)置為透明即可。

          因此得到以下的CSS代碼,設(shè)置不同方向border的寬度,三角形的形狀也會跟著變。

          下三角形CSS代碼

          同理,只要掌握了其中一個方向的三角形原理,就會輕松寫出其他方向三角形的CSS代碼。

          這里直接給出上三角形的CSS代碼。

          上三角形CSS代碼

          左三角形的CSS代碼如下所示。

          左三角形CSS代碼

          右三角形的CSS代碼如下所示。

          右三角形CSS代碼

          正方形-四種顏色

          接下來我們看一種基本的只用border設(shè)計的形狀。

          圖形

          它的實現(xiàn)方式也很簡單,只需要將width和height設(shè)置為0,然后將border四個方向的寬度設(shè)置成一樣的即可。

          得到的代碼如下所示。

          CSS代碼

          直角三角形

          基于上述的實現(xiàn),我們可以得到左下,左上,右上,右下四種三角形。

          首先看看基本形狀。

          直角三角形

          看到圖形后,我們很容易發(fā)現(xiàn),只要隱藏掉連接的兩個方向的border,顯示出另外兩個方向的border,就可以得到直角三角形。

          這里我們只展示出左上三角形的CSS代碼。

          左上直角三角形CSS代碼

          其他方向的直角三角形代碼可類比得出,大家可以試一下。

          六角星

          首先我們看看六角星的形狀。

          六角星

          看到這個圖形,大家應(yīng)該能想到可以由上下兩個三角形構(gòu)成,只要將上下兩個三角形位置對應(yīng)準(zhǔn)確。

          這里為了節(jié)省頁面元素的空間,我們可以采用偽元素去實現(xiàn)。

          • 將頁面顯示元素設(shè)置為上三角形。

          • 利用:after偽元素設(shè)置下三角形。

          • 設(shè)置偽元素的position為absolute,調(diào)節(jié)right和top值。

          通過上述分析,我們得到以下CSS代碼。

          六角星CSS代碼

          圓形

          與border屬性搭配使用的還有一個很常用的屬性,那就是border-radius。

          border-radius是專門設(shè)置圓角的,可以讓90度角變?yōu)閳A角。

          我們首先看看最基本的圓形的樣子。

          圓形

          其實我們只需要將border-radius屬性設(shè)置為寬或者高的一半以上即可。代碼如下所示。

          圓形

          同心圓

          我們來看看同心圓的樣子。

          同心圓

          同心圓只需要設(shè)置一個border邊框,給border設(shè)置一個特殊的背景色,給div設(shè)置成白色背景即可。

          同心圓CSS代碼

          半圓

          我們來看看半圓的形狀。

          半圓

          半圓的效果是如何實現(xiàn)的呢?

          • 首先元素自身高度設(shè)置為0,設(shè)定寬度值。

          • 設(shè)定上部和右部的border。

          • 設(shè)定左上角和右上角的border-radius值。

          得到的代碼如下所示。

          上半圓

          同理,下半圓,左半圓和右半圓修改對應(yīng)的值就可以獲得。

          結(jié)束語

          今天這篇文章主要通過border屬性,畫出了一系列簡易的圖形,這在實際中是很實用的,大家學(xué)會了嗎?


          主站蜘蛛池模板: 久久久久国产一区二区 | 无码人妻精品一区二区在线视频| 在线视频一区二区三区四区| 精品成人一区二区三区免费视频| 日韩制服国产精品一区| 日本一区二区视频| 日韩精品无码视频一区二区蜜桃 | 日本大香伊一区二区三区| 成人精品视频一区二区| 无码一区二区三区| 人妻免费一区二区三区最新| 国产免费私拍一区二区三区| 中文字幕乱码一区久久麻豆樱花| 日韩电影一区二区| 国产伦理一区二区| 亲子乱AV视频一区二区| 国产一区二区在线观看app| 一区二区国产精品| 国产av福利一区二区三巨| 精品乱子伦一区二区三区高清免费播放 | 日韩精品一区二区三区国语自制 | 亚洲av日韩综合一区在线观看| 国产美女口爆吞精一区二区| 国产观看精品一区二区三区| 日本高清无卡码一区二区久久| 蜜桃视频一区二区三区| 国产另类ts人妖一区二区三区 | 好爽毛片一区二区三区四| 亲子乱AV视频一区二区| 久久久久人妻精品一区二区三区| 91在线视频一区| 精品国产日韩亚洲一区91| 日韩视频一区二区| 无码乱人伦一区二区亚洲| 亚洲AV成人精品日韩一区| 国产美女av在线一区| 99在线精品一区二区三区| asmr国产一区在线| 国产成人欧美一区二区三区| 中文字幕亚洲一区| 国产午夜精品一区二区三区极品|