python-opencv霍夫变换

霍夫变换是一种可以检测任何形状的流行技术,即使形状有缺失或变形,仍然可以检测出形状。

常用霍夫变换检测线

一条线可以表示为y=mx+c或以参数形式表示为\rho =xcos\theta +ysin\theta,其中\rho是从原点到该线的垂直距离,而\theta是由该垂直线和水平轴所形成的角度以逆时针方向测量。

如图所示:

python-opencv霍夫变换_第1张图片

 现在看一下霍夫变换如何处理线条。任何一条线都可以用(\rho ,\theta )这两个术语表示。因此,首先创建2D数组或累加器(以保存两个参数的值),并将其初始设置为0。让行表示\rho,列表示\theta。阵列的大小取决于所需的精度。

opencv中的霍夫线变换 -> cv2.Houghlines()  它只是返回一个:math:(rho,theta)值得数组。\rho以像素为单位,\theta以弧度为单位。

第一个参数,输入的是二进制图像,因此在应用霍夫变换之前,应用阈值或Canny边缘检测。

第二和第三参数分别是\rho\theta的精度。

第四个参数是阈值,这意味着应将其视为行的最低投票。票数取决于线上的点数。因此,它表示检测到的最小线长。

看实际应用,选着棋盘格图案试一试

# 导包
import cv2 as cv
import numpy as np

img = cv.imread('D:/chess.png')
# 灰度图
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# Canny边缘检测
edges = cv.Canny(gray,50,150,apertureSize=3)
# 霍夫线检测
lines = cv.HoughLines(edges,1,np.pi/180,200)
for line in lines:
    rho,theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 =int(x0 + 1000*(-b))
    y1 = int(y0 + 1000 * (a))
    x2 =int(x0 - 1000*(-b))
    y2 = int(y0 - 1000 * (a))
    # 画线
    cv.line(img,(x1,y1),(x2,y2),(0,0,255),2)
# 保存
cv.imwrite('D:/houghlines.jpg',img)

输出效果:

python-opencv霍夫变换_第2张图片

常用霍夫变换检测圆

 圆在数学上表示为(x-x_{0})^{2}+(y-y_{0})^{2}=r^{2},其中(x_{0},y_{0})是圆的中心,r是圆的半径。从公式上可以看到有3个参数,因此需要3D累加器进行霍夫变换,这将非常低效。因此opencv使用边缘的梯度信息的方法。

opencv中的霍夫圆变换 -> cv2.HoughCircles()  

# 导包
import cv2 as cv
import numpy as np

# 导入图片,直接变灰度的
img = cv.imread('D:/hou/jingtou.png',0)
# 中值滤波
img = cv.medianBlur(img,5)
# cimg变回BGR图像
cimg = cv.cvtColor(img,cv.COLOR_GRAY2BGR)
# 霍夫圆变换
circles = cv.HoughCircles(img,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(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    # 绘制圆心
    cv.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv.imwrite('D:/houghcircle.jpg',cimg)

输出效果:

python-opencv霍夫变换_第3张图片

 

你可能感兴趣的:(python-opencv,opencv,计算机视觉,人工智能)