opencv进阶学习笔记11:cannny边缘检测,直线检测,圆检测
基礎版筆記傳送門
python3+opencv學習筆記匯總目錄(適合基礎入門學習)
進階版筆記目錄鏈接:
python+opencv進階版學習筆記目錄(適合有一定基礎)
cannny邊緣檢測
基礎版邊緣講解鏈接:
opencv學習筆記18:canny算子邊緣檢測原理及其函數(shù)使用
1cannny算法介紹
非極大值抑制:在獲得梯度和方向,去除所有不是邊界的點。實現(xiàn)方向:逐漸遍歷像素點,判斷當前像素點是否是周圍像素點中具有相同方向梯度的最大值。是保留,不是則為0.
cannny代碼實現(xiàn)
edges=cv2.Canny(image,threshold1,threshold2)
edges:處理結果
image:原始圖像
threshold1:minVal
threshold2:maxVal
如果想讓邊界細節(jié)更多,則把threshold1和threshold2設小些。
blurred = cv.GaussianBlur(image, (3, 3), 0)#高斯模糊,降低噪聲。canny對噪聲比較敏感,也不能模糊太厲害,去掉了邊緣信息。
edge_output = cv.Canny(xgrad, ygrad, 50, 150)
#edge_output = cv.Canny(gray, 50, 150)
是相同的
高閾值應該是低閾值的3倍
直線檢測
一、原理介紹:
1、對于直角坐標系中的任意一點A(x0,y0),經(jīng)過點A的直線滿足Y0=k*X0+b.(k是斜率,b是截距)
2、那么在X-Y平面過點A(x0,y0)的直線簇可以用Y0=k*X0+b表示,但對于垂直于X軸的直線斜率是無窮大的則無法表示。因此將直角坐標系轉換到極坐標系就能解決該特殊情況。
3、在極坐標系中表示直線的方程為ρ=xCosθ+ySinθ(ρ為原點到直線的距離),如圖所示:
直線檢測代碼實現(xiàn)方法1
1、標準霍夫線變換
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )
參數(shù):
image:邊緣檢測的輸出圖像. 它應該是個灰度圖 (但事實上是個二值化圖)
lines:儲存著檢測到的直線的參數(shù)對 的容器,存儲的是rho,theta
rho:參數(shù)極徑 以像素值為單位的分辨率. 我們使用 1 像素.
theta:參數(shù)極角 以弧度為單位的分辨率. 我們使用 1度 (即CV_PI/180)
theta:要”檢測” 一條直線所需最少的的曲線交點
srn and stn: 參數(shù)默認為0.
直線檢測代碼實現(xiàn)方法2
2、統(tǒng)計概率霍夫線變換
void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold,double minLineLength=0, double maxLineGap=0 )
參數(shù):
image: 邊緣檢測的輸出圖像. 它應該是個灰度圖 (但事實上是個二值化圖) *
lines: 儲存著檢測到的直線的參數(shù)對 的容器,也就是線段兩個端點的坐標
rho : 參數(shù)極徑 以像素值為單位的分辨率. 我們使用 1 像素.
theta: 參數(shù)極角 以弧度為單位的分辨率. 我們使用 1度 (即CV_PI/180)
threshold: 要”檢測” 一條直線所需最少的的曲線交點
minLinLength: 能組成一條直線的最少點的數(shù)量. 點數(shù)量不足的直線將被拋棄.線段的最小長度
maxLineGap:線段上最近兩點之間的閾值
圓檢測
1原理
圓周上任意三點所確定的圓,經(jīng)Hough變換后在三維參數(shù)空間應對應一點。遍歷圓周上所有點,任意三個點所確定的候選圓進行
投票。遍歷結束后,得票數(shù)最高點(理論上圓周上任意三點確定的圓在Hough變換后均對應三維參數(shù)空間中的同一點)所確定的圓
即為該圓周上,絕大多數(shù)點所確定的圓(以下稱為當選圓),即絕大多數(shù)點均在該當選圓的圓周上,以此確定該圓。
圓形的表達式為(x?xcenter)2+(y?ycenter)2=r2(x?xcenter)2+(y?ycenter)2=r2,一個圓環(huán)的確定需要三個參數(shù)。那么霍夫變換的累加器必須是三維的,但是這樣的計算效率很低。
這里opencv中使用霍夫梯度的方法,這里利用了邊界的梯度信息。
首先對圖像進行canny邊緣檢測,對邊緣中的每一個非0點,通過Sobel算法計算局部梯度。那么計算得到的梯度方向,實際上就是圓切線的法線。三條法線即可確定一個圓心,同理在累加器中對圓心通過的法線進行累加,就得到了圓環(huán)的判定。
2opencv API
因為霍夫圓檢測對噪聲比較敏感,所以首先要對圖像做中值濾波。
基于效率考慮,Opencv中實現(xiàn)的霍夫變換圓檢測是基于圖像梯度的實現(xiàn),分為兩步:
檢測邊緣,發(fā)現(xiàn)可能的圓心
基于第一步的基礎上從候選圓心開始計算最佳半徑大小
cv2.HoughCircles函數(shù)的參數(shù)
cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)
image為輸入圖像,需要灰度圖
method為檢測方法,常用CV_HOUGH_GRADIENT
dp為檢測內側圓心的累加器圖像的分辨率于輸入圖像之比的倒數(shù),如dp=1,累加器和輸入圖像具有相同的分辨率,如果dp=2,累計器便有輸入圖像一半那么大的寬度和高度
minDist表示兩個圓之間圓心的最小距離,圓心距離小于mimDist認為為同一個圓
param1有默認值100,它是method設置的檢測方法的對應的參數(shù),對當前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示傳遞給canny邊緣檢測算子的高閾值,而低閾值為高閾值的一半
param2有默認值100,它是method設置的檢測方法的對應的參數(shù),對當前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示在檢測階段圓心的累加器閾值,它越小,就越可以檢測到更多根本不存在的圓,而它越大的話,能通過檢測的圓就更加接近完美的圓形了
minRadius有默認值0,圓半徑的最小值
maxRadius有默認值0,圓半徑的最大值
import cv2 as cv import numpy as npdef detect_circles_demo(image):dst = cv.pyrMeanShiftFiltering(image, 10, 100)#均值偏移濾波cv.imshow("dst", dst)cimage = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)#灰度圖circles = cv.HoughCircles(cimage, cv.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0)circles = np.uint16(np.around(circles))#取整for i in circles[0, :]:cv.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2)#在原圖上畫圓,圓心,半徑,顏色,線框cv.circle(image, (i[0], i[1]), 2, (255, 0, 0), 2)#在原圖上畫圓心 cv.imshow("circles", image)print("--------- Python OpenCV Tutorial ---------") src = cv.imread("coins.jpg") cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.imshow("input image", src) detect_circles_demo(src) cv.waitKey(0) cv.destroyAllWindows()如果沒有下面這一行
dst = cv.pyrMeanShiftFiltering(image, 10, 100)#均值偏移濾波結果
原理:
meanShfit均值漂移算法是一種通用的聚類算法,它的基本原理是:對于給定的一定數(shù)量樣本,任選其中一個樣本,以該樣本為中心點劃定一個圓形區(qū)域,求取該圓形區(qū)域內樣本的質心,即密度最大處的點,再以該點為中心繼續(xù)執(zhí)行上述迭代過程,直至最終收斂??梢岳镁灯扑惴ǖ倪@個特性,實現(xiàn)彩色圖像分割,
Opencv中對應的函數(shù)是pyrMeanShiftFiltering。這個函數(shù)嚴格來說并不是圖像的分割,而是圖像在色彩層面的平滑濾波,它可以中和色彩分布相近的顏色,平滑色彩細節(jié),侵蝕掉面積較小的顏色區(qū)域,
第一個參數(shù)src,輸入圖像,8位,三通道的彩色圖像,并不要求必須是RGB格式,HSV、YUV等Opencv中的彩色圖像格式均可;
第二個參數(shù)dst,輸出圖像,跟輸入src有同樣的大小和數(shù)據(jù)格式;
第三個參數(shù)sp,定義的漂移物理空間半徑大小;
第四個參數(shù)sr,定義的漂移色彩空間半徑大小;
第五個參數(shù)maxLevel,定義金字塔的最大層數(shù);
第六個參數(shù)termcrit,定義的漂移迭代終止條件,可以設置為迭代次數(shù)滿足終止,迭代目標與中心點偏差滿足終止,或者兩者的結合;
pyrMeanShiftFiltering函數(shù)的執(zhí)行過程是這樣的:
迭代空間構建
求取迭代空間的向量并移動迭代空間球體后重新計算向量,直至收斂(一個圖像,然后選取一個球形,求得所有點相對于中心點的色彩向量之和后,移動選取的球形繼續(xù)操作,有點類似卷積層)
更新輸出圖像dst上對應的初始原點P0的色彩值為本輪迭代的終點Pn的色彩值,如此完成一個點的色彩均值漂移。
4.輸入圖像src上其他點,依次執(zhí)行步驟1,、2、3,遍歷完所有點位后,整個均值偏移色彩濾波完成
半徑越大,圖像的細節(jié)就丟失的越多
電氣專業(yè)的計算機萌新,寫博文不容易。如果你覺得本文對你有用,請點個贊再走,謝謝。
總結
以上是生活随笔為你收集整理的opencv进阶学习笔记11:cannny边缘检测,直线检测,圆检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 比亚迪秦前塑料盖如何的打开?
- 下一篇: opencv进阶学习笔记12:轮廓发现和