不说废话了,感谢大神的文章霍夫变换。我还是重点说一下关于程序的部分吧
先说的是函数HoughLines。
cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn]]])
image是输入的图像
rho是以像素为单位的累加器的距离分辨率
theta是在弧度内的蓄能器的角度分辨率
threshold其实是阈值,当累加器超过一定的范围才看作是直线
关于阈值要根据情况不断的实验,rho和theta一般就是例子中的样子了。函数的输出结果是个三维的矩阵,实际要用到的时候可以转化为二维的。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img1=cv2.imread('C:/Users/dell/Desktop/c1.jpg')
#解释一下我们之所以要把图象灰化再利用canny找出边界是因为轮廓上出现上出现直线的概率更大。
gray=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
edges=cv2.Canny(gray,5,120)
#lines的shape是(m,1,n),lines1是(m,n)
lines=cv2.HoughLines(edges,1,np.pi/180,200)
lines1 = lines[:,0,:]
for rho,theta in lines1[:]:
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))
cv2.line(img1,(x1,y1),(x2,y2),(0,0,255),2)
cv2.imshow('image',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
和大神说的一样就算有canny算法,现实中要考虑的点也是很多的,所以HoughLinesP函数就是一种随机选取点的方法。有点类似随机梯度下降算法,牺牲一部分想能换取时间
cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])
其他的参数和上一个函数一样
minLineLength是线的最短长度(比这个短的都忽略了)
maxLinegap两条直线的最大间隔,小于这个间隔的看成一条直线。
这次输出的就不是关于直线的参数了,而是直线的坐标。
img1=cv2.imread('C:/Users/dell/Desktop/u=.jpg')
gray=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
edges=cv2.Canny(gray,50,150)
lines=cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength=100,maxLineGap=10)
lines1 = lines[:,0,:]
print(lines.shape)
print(lines1.shape)
for x1,y1,x2,y2 in lines1[:]:
cv2.line(img1,(x1,y1),(x2,y2),(0,0,255),2)
cv2.imshow('image',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
这里输出矩阵的规模也和上面的一样,要把三维的变成2维的。
cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])
image是输入图象
method仅有一个cv2.HOUGH_GRADIENT
dp累加器分辨率与图像分辨率的反比。例如,如果dp=1,累加器与输入图像具有相同的分辨率。如果dp=2,则累加器的宽度和高度为原来的一半。
minDist检测圆的中心之间的最小距离。如果参数太小,可能会错误地检测到多个相邻的圆。如果太大,可能会漏掉一些圆。
param1第一个method-specific参数。在CV_HOUGH_GRADIENT的情况下,它是两个传递到Canny()边缘检测器的更高阈值(下一个是两倍小)。
param2第二个method-specific参数。在CV_HOUGH_GRADIENT的情况下,它是检测阶段圆形中心的累加器阈值。它越小,就会发现更多的假圆。圆形,对应于较大的累加器值,将首先返回。
minradius圆的最小半径
maxradius圆的最大半径
这里输入灰度图象就好了,注意调参,不同的参数会有不同的圆
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('C:/Users/dell/Desktop/ux.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
circles1=cv2.HoughCircles(gray,cv2.HOUGH_GRADIENT,1,100,param1=100,param2=30,minRadius=10,maxRadius=300)
circles=circles1[0,:,:]
circles=np.uint16(np.around(circles))
print(circles.shape)
print(circles1.shape)
for i in circles[:]:
cv2.circle(img, (i[0], i[1]), i[2], (255, 0, 0), 5) # 画圆
cv2.circle(img, (i[0], i[1]), 2, (255, 0, 255), 10)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()