OpenCV-Python学习笔记-霍夫变换(Hough Transformation)

霍夫变换是一种可用于隔离图像中特定形状的特征的技术,在给定局部特征(可能有噪声)的情况下,对于计算特征的全局描述(无需事先知道解决方案类别的数量)特别有用。 霍夫变换用于直线检测的动机是,每个输入测量值(例如坐标点)表明其对全局一致解(例如产生该图像点的直线)的贡献。

检测直线原理

在直角坐标系中,直线的表示形式为:
y = a ⋅ x + b y=a \cdot x+b y=ax+b
同样一条直线,在仿射坐标系 ( r , θ ) (r,\theta) (r,θ)中的表示形式为:

r = x ⋅ cos ⁡ θ + y ⋅ sin ⁡ θ r=x \cdot \cos \theta+y \cdot \sin \theta r=xcosθ+ysinθ

  • r r r 表示坐标原点与直线的距离
  • θ θ θ 表示 r r r 向量与 x x x 坐标轴之间的夹角
  • 对于直线上的任意一点 ( x , y ) (x,y) (x,y) r r r θ θ θ 是常数(几何上可证明)

在这里插入图片描述

在直角坐标系中绘制过任意一点 ( x 0 , y 0 ) (x_{0},y_{0}) (x0,y0)直线的 ( r , θ ) (r,\theta) (r,θ)曲线,此时 r r r θ θ θ不断变化,曲线反映的是描述过任意一点直线的两个特征:原点矩 r r r和夹角 θ θ θ。假设A、B两点在同一直线上,因为在同一直线上的点,不管 x , y x,y x,y 如何变化,其 r r r θ θ θ 均为定值,所以A、B两者的 ( r , θ ) (r,θ) (r,θ)曲线会在某一点上相交,这一点表示所在直线的 r r r θ θ θ

所以,霍夫变换的原理就是检查输入点的 ( r , θ ) (r,θ) (r,θ)曲线,如果他们满足一定的重合阈值条件,则判定他们是同一条直线。

基本霍夫变换-直线实例

OpenCV-Python中使用霍夫变换检测直线的函数是cv2.HoughLines(),函数原型如下:

lines =	cv.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]])
  • image:要检测的二值图
  • rho:距离 r r r的精度,值越大,考虑越多的线
  • theta:角度 θ θ θ的精度,值越小,考虑越多的线
  • threshold:累加数阈值,值越小,考虑越多的线

参数的详细介绍,参考cv2.HoughLines

import cv2
import numpy as np 

img = cv2.imread('shapes.jpg')
drawing = np.zeros(img.shape,dtype=np.uint8)
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
edges = cv2.Canny(gray,50,150)
lines = cv2.HoughLines(edges,0.8,np.pi/180,90)

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))

    cv2.line(drawing, (x1, y1), (x2, y2), (0, 0, 255))
cv2.imshow('res',drawing)
cv2.waitKey()

在这里插入图片描述
参考链接:http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm

统计概率霍夫变换-直线实例

上面介绍的是最基本的霍夫变换,缺点是计算量较大,而且算出来的结果是 r , θ r,θ r,θ并不直观,改进的方法称为统计概率霍夫变换,在opencv-python中的函数原型是cv.HoughLinesP

lines =	cv.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])
  • minLineLength:线段的最小长度
  • maxLineGap:线段的最大长度
drawing = np.zeros(img.shape[:], dtype=np.uint8)
lines = cv2.HoughLinesP(edges, 0.8, np.pi / 180, 90,
                        minLineLength=50, maxLineGap=10)

for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(drawing, (x1, y1), (x2, y2), (0, 255, 0), 1, lineType=cv2.LINE_AA)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值