0
点赞
收藏
分享

微信扫一扫

CV15 轮廓检测:霍夫变换原理及应用

文章目录

1.基本原理

1.1数学分析

  • 如下图,y=kx+q
cv151

我们可以把k看作自变量,把q看作因变量,则有:
A : q = − k x 1 + y 1 B : q = − k x 2 + y 2 A: q=-kx_1+y_1\\ B: q=-kx_2+y_2 A:q=kx1+y1B:q=kx2+y2
这个过程,称作霍夫变换,在霍夫空间上,可得到一个点,如下图所示:

CV15

由此可见:坐标系的直线,经霍夫变换后,变成了霍夫空间上的点,如下图:

CV153
  • 若有A(x1,y1) 、B(x2,y2),且x1!=x2,y1!=y2

当 q A = q B , k A = m × K B − x 1 ⋅ k + y 1 = − x 2 ⋅ k + y 2 当q_A=q_B,k_A=m\times K_B\\ -x_1\cdot k + y1 = -x_2\cdot k + y_2\\ qA=qB,kA=m×KBx1k+y1=x2k+y2
有交点Q,在交点Q处,x1=x2,y1=y2

此时,可以说明A/B在同一条直线上

k变换,q也就随之变换。这个过程表示经过D点的直线,360°旋转,如下图:

  • 多点共线的情况,如下图:
sadsad

虽然图二中有多个交点,但我们主要关注的是三线相交的情况,这也是霍夫变换的后处理的基本方式:选择由尽可能多直线汇成的点

  • 但是仅用k、q表示霍夫空间是有问题的,因为我们忽视了一种特殊情况:直线与x轴垂直的情况
ddfdsf

k=∞是不方便表示的,所以我们必须改变一下坐标系:用极坐标表示点,线
x 1 = ρ = c o s θ y 1 = ρ s i n θ ρ = x c o s θ + y s i n θ 所 以 , 可 用 [ ρ , θ ] 表 示 一 个 点 x_1=\rho =cos\theta\\ y_1=\rho sin\theta\\ \rho =xcos\theta+ysin\theta\\ 所以,可用[\rho,\theta]表示一个点 x1=ρ=cosθy1=ρsinθρ=xcosθ+ysinθ[ρ,θ]
霍夫空间也随之改变,但也就是点的曲线变了而已

k4Rn9P

1.2图像处理应用

那么我们应如何把它用在图像处理中呢?

  • 假设我们图像中有一段有8个像素点组成直线

    • 1.建立直角坐标系
    • 2.将第一个像素点的(x,y)代入公式中

    ρ = x c o s θ + y s i n θ \rho =xcos\theta+ysin\theta\\ ρ=xcosθ+ysinθ

    • 3.此时角度作为自变量,我们选用遍历查询的办法,不断旋转增加角度(记住,角度增加量极小,但下图为了方便计算,我每次旋转都增加了45°)
    • 4.在(1,8)处有5个ρ值,我们将结果记录下来
    • 5.然后计算(3,6)坐标处,依此类推,也将结果记录下来
    • 6.每个像素点的旋转的数据都记录下来之后,找哪一个ρ值出现的最多(下图是 (9√2)/2)
    • 7.再次带(9√2)/2到公式(4)中,得到角度
    • 8.计算出**[ρ,θ]**,即可表示出一条线了
6

以上就是标准霍夫变换的原理

但我们一般不用标准霍夫变换,而是用概率霍夫变换😂😂😂


参考资料:霍夫变换直线检测(Line Detection)原理及示例

​ (四十八)通俗易懂理解——霍夫变换原理

2.概率霍夫变换

2.1标准霍夫与概率霍夫

  • 标准霍夫变换:把图像映射到它的参数空间上,它需要计算所有的M个边缘点,这样它的运算量和所需内存空间都会很大。

  • 概率霍夫变换:如果在输入图像中只是处理m(m<M)个边缘点,则这m个边缘点的选取是具有一定概率性的,因此该方法被称为概率霍夫变换。该方法还有一个重要的特点就是能够检测出线端,即能够检测出图像中直线的两个端点,确切地定位图像中的直线。概率霍夫变换的优点:只分析图像点的一部分(标准的是分析全部),并估计这些点属于同一条线的概率,计算强度小,运行速度快

2.2概率霍夫检测步骤

  1. 随机抽取图像中的一个特征点,即边缘点,如果该点已经被标定为是某一条直线上的点,则继续在剩下的边缘点中随机抽取一个边缘点,直到所有边缘点都抽取完了为止;
  2. 对该点进行霍夫变换,并进行累加和计算;
  3. 选取在霍夫空间内值最大的点,如果该点大于阈值的,则进行步骤4,否则回到步骤1;
  4. 根据霍夫变换得到的最大值,从该点出发,沿着直线的方向位移,从而找到直线的两个端点;
  5. 计算直线的长度,如果大于某个阈值,则被认为是好的直线输出,回到步骤1。

3.霍夫变换检测线

3.1cv2.HoughLinesP()函数

HoughLinesP函数就是利用概率霍夫变换来检测直线的

示例:lines = cv2.HoughLinesP(edges,1,np.pi/180,30,minLineLength,maxLineGap)

3.2线检测程序

import cv2 as cv
import numpy as np
img = cv.imread('test2.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray,50,150,apertureSize = 3)
lines = cv.HoughLinesP(edges,1,np.pi/180,100,minLineLength=100,maxLineGap=10)
for line in lines:
  x1,y1,x2,y2 = line[0]
  cv.line(img,(x1,y1),(x2,y2),(0,255,0),2)
cv.imshow('houghlines5.jpg',img)
cv.waitKey()
cv.destroyAllWindows()
houghlines5

注意!!!

市面上有些教材书上是这么写的,无法得到理论结果💔

fasdf

正确的答案为

for line in lines:
  x1,y1,x2,y2 = line[0]
  cv.line(img,(x1,y1),(x2,y2),(0,255,0),2)

4.霍夫变换检测圆

Opencv中还有一个函数cv2.HoughCircles,它通过霍夫梯度法,实现了圆的检测

参考资料:opencv —— HoughCircles 霍夫圆变换原理及圆检测

4.1cv2.HoughCircles()函数

示例:circle=cv2.HoughCircles(gray_img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0)

4.2圆检测程序

import cv2
import numpy as np

planets = cv2.imread('planet_glow.jpg')
gray_img = cv2.cvtColor(planets,cv2.COLOR_BGR2GRAY)
gray_img = cv2.medianBlur(gray_img,5)

circles = cv2.HoughCircles(gray_img,cv2.HOUGH_GRADIENT,1,120,param1=80,param2=35,minRadius=0,maxRadius=0)
print(circles)
circles = np.uint16(np.around(circles))

for i in circles[0,:]:
    cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2)

    cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('planet',planets)
cv2.waitKey()
cv2.destroyAllWindows()

效果显著!😎😎😎

planet

5.结语

Opencv入门篇已经学完了,接下来有其它的事情❌,这个专栏预计停更一两周📵

车牌检测,周三看看能不能做完😭😭😭

忙完之后,估计就到了用Haar级联实现人脸检测🐵

举报

相关推荐

0 条评论