日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv进阶学习笔记11:cannny边缘检测,直线检测,圆检测

發(fā)布時間:2024/9/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv进阶学习笔记11:cannny边缘检测,直线检测,圆检测 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基礎版筆記傳送門
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設小些。

import numpy as np import cv2 as cvdef edge_demo(image):blurred = cv.GaussianBlur(image, (3, 3), 0)#高斯模糊,降低噪聲。canny對噪聲比較敏感,也不能模糊太厲害,去掉了邊緣信息。gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)#轉化為灰度圖# X Gradient 求x梯度xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0)# Y Gradient #求y梯度ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1)#edgeedge_output = cv.Canny(xgrad, ygrad, 50, 150)#edge_output = cv.Canny(gray, 50, 150)cv.imshow("Canny Edge", edge_output)dst = cv.bitwise_and(image, image, mask=edge_output)#生成彩色邊界圖cv.imshow("Color Edge", dst) print("--------- Python OpenCV Tutorial ---------") src = cv.imread("duoren.jpg") cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.imshow("input image", src) edge_demo(src) cv.waitKey(0) cv.destroyAllWindows()

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.

import cv2 as cv import numpy as npdef line_detection(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)#轉化為灰度edges = cv.Canny(gray, 50, 150, apertureSize=3)#求取邊緣 窗口大小apertureSize=3lines = cv.HoughLines(edges, 1, np.pi/180, 200)#np.pi/180每次偏轉1度for line in lines:#print(type(lines))print(line)rho, theta = line[0]a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0+1000*(-b))y1 = int(y0+1000*(a))x2 = int(x0-1000*(-b))y2 = int(y0-1000*(a))cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)cv.imshow("image-lines", image)print("--------- Python OpenCV Tutorial ---------") src = cv.imread("zhiixian.jpg") cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.imshow("input image", src) line_detection(src) cv.waitKey(0)cv.destroyAllWindows()

直線檢測代碼實現(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:線段上最近兩點之間的閾值

import cv2 as cv import numpy as npdef line_detect_possible_demo(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 50, 150, apertureSize=3)lines = cv.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=50, maxLineGap=10)for line in lines:print(type(line))x1, y1, x2, y2 = line[0]cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)cv.imshow("line_detect_possible_demo", image) print("--------- Python OpenCV Tutorial ---------") src = cv.imread("zhiixian.jpg") cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) cv.imshow("input image", src) line_detect_possible_demo(src) cv.waitKey(0) cv.destroyAllWindows()

圓檢測

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边缘检测,直线检测,圆检测的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。