利用Opencv中Houghline方法实现直线检测


Posted in Python onFebruary 11, 2018

利用Opencv中的Houghline方法进行直线检测—python语言

这是给Python部落翻译的文章,请在这里看原文。

在图像处理中,霍夫变换用来检测任意能够用数学公式表达的形状,即使这个形状被破坏或者有点扭曲。

下面我们将看到利用HoughLine算法来阐述霍夫变化进行直线检测的原理,把此算法应用到特点图像的边缘检测是可取的。边缘检测方法请参考这篇文章?边缘检测。

Houghline算法基础

直线可以表示为y=mx+c,或者以极坐标形式表示为r=xcosθ+ysinθ,其中r是原点到直线的垂直距离,θ是水平轴顺时针方向到垂直线的夹角(这个方向取决于坐标的形式,在OpenCV就是采用这种极坐标形式)。

利用Opencv中Houghline方法实现直线检测

因此任意的曲线都可以用两个参数(r,θ)表示。

HoughLine算法原理:

  • 首先建立一个二维的数组或者累加器(用来保存这两个参数),并初始化为零;
  • 这个二维数组的行代表不同的r,而列代表角度θ;
  • 数组的大小取决于算法的精度。假设所需角度的精度精确到1∘,那么就需要180列(直线的最大角度是180)。
  • 对于r,最大的可能距离是图像的对角长度,因此若需要一个像素的精度,那么需要把行数设为图像对角线的长度。

例子:

假设一幅100x100的图像,在图像中间有一条水平直线。设直线的第一个点的坐标为(x,y),在直线方程中,令参数θ=0,12,⋯,180,观查参数r变化。对每一个参数对(r,θ),在累加器中将(r,θ)对应的单元格中的值递增1,比如现在在累加器中,某个单元(50,90)的值等于1,其它的值也如此。

对于直线上的第二个点,重复上述操作。将得到的参数对(r,θ)的对应值继续递增,然后(50,90)对应的值等于2。实现上我们是对参数对(r,θ)进行投票,对直线上的每一个点重复上述操作,对每一个点,单元格(50,90)对应的值会递增,或者说投票给参数对(50,90),而会或者不会投票给其它参数对。以这种方式,最后单元格(50,90)的值将会是最大的值。然后搜索累加器的最大值,将会找到参数对(50,90)。也就是说,在图像中找到了到原点距离为50,角度为90的一条直线。

利用Opencv中Houghline方法实现直线检测

上述算法的过程被封装成OpenCV函数cv2.HoughLines(),函数返回(r,θ)的一个数组,其中r的单位为像素,θ的单位为弧度。

# Python program to illustrate HoughLine
# method for line detection
import cv2
import numpy as np

# Reading the required image in 
# which operations are to be done. 
# Make sure that the image is in the same 
# directory in which this python program is
img = cv2.imread('xyz.jpg')

# Convert the img to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# Apply edge detection method on the image
edges = cv2.Canny(gray,50,150,apertureSize = 3)

# This returns an array of r and theta values
lines = cv2.HoughLines(edges,1,np.pi/180, 200)

# The below for loop runs till r and theta values 
# are in the range of the 2d array
for r,theta in lines[0]:

 # Stores the value of cos(theta) in a
 a = np.cos(theta)

 # Stores the value of sin(theta) in b
 b = np.sin(theta)

 # x0 stores the value rcos(theta)
 x0 = a*r

 # y0 stores the value rsin(theta)
 y0 = b*r

 # x1 stores the rounded off value of (rcos(theta)-1000sin(theta))
 x1 = int(x0 + 1000*(-b))

 # y1 stores the rounded off value of (rsin(theta)+1000cos(theta))
 y1 = int(y0 + 1000*(a))

 # x2 stores the rounded off value of (rcos(theta)+1000sin(theta))
 x2 = int(x0 - 1000*(-b))

 # y2 stores the rounded off value of (rsin(theta)-1000cos(theta))
 y2 = int(y0 - 1000*(a))

 # cv2.line draws a line in img from the point(x1,y1) to (x2,y2).
 # (0,0,255) denotes the colour of the line to be 
 #drawn. In this case, it is red. 
 cv2.line(img,(x1,y1), (x2,y2), (0,0,255),2)

# All the changes made in the input image are finally
# written on a new image houghlines.jpg
cv2.imwrite('houghlines3.jpg', img)

函数(cv2.HoughLines(edges, 1, np.pi/180,200))

  • 第一个参数是输入图像,且必须是二值图像,在进行霍夫变换之前需要采用阈值方法的边缘检测;
  • 第二和第三个参数分别是r,θ对应的精度;
  • 第四个参数是阈值,判定为直线投票数的最小值;
  • 注意,投票数取决于直线上点的个数,因此这个阈值代表了检测到的直线的最短长度。

利用Opencv中Houghline方法实现直线检测

总结

  • 在图像分析应用中,边缘分割点的坐标(即X,Y)是已知的,在直线的参数方程中作为输入,而r,θ是我们要找的未知变量;
  • 对每一个角度θ,求出r的值,也就是将笛卡尔图像空间的点映射到霍夫参数极坐标空间的曲线,这种点到曲线的变换就是直线的霍夫变换;
  • 这种变换是通过量化霍夫参数为有限的间隔或者累加器单元来实现的,随着算法的运行,每一个(X,Y)转换成离散的(r,θ)曲线,曲线上的点对应的累加器(二维数组)的值会递增;
  • 累加器中的峰值就代表了图像中有相应直线的存在。

霍夫变换的应用

  • 用于分离图像中特殊形状的特征;
  • 可以容忍特征边界描述的误差,并且不受噪声的干扰;
  • 广泛用于条形码扫描、验证和识别。

文章作者是Pratima Upadhyay,如果你喜欢GeeksforGeeks,并且愿意分享,可以利用contribute.geeksforgeeks.org写文章,然后发送到contribute@geeksforgeeks.org,在GeeksforGeeks中看到自己的文章,帮助更多的Geeks。

若发现错误欢迎指正,也欢迎评论。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python时间整形转标准格式的示例分享
Feb 14 Python
Centos Python2 升级到Python3的简单实现
Jun 21 Python
Python简单实现控制电脑的方法
Jan 22 Python
Python实现的各种常见分布算法示例
Dec 13 Python
python实现kmp算法的实例代码
Apr 03 Python
Python寻找路径和查找文件路径的示例
Jul 10 Python
在python image 中安装中文字体的实现方法
Aug 22 Python
python SVD压缩图像的实现代码
Nov 05 Python
python 无损批量压缩图片(支持保留图片信息)的示例
Sep 22 Python
python3 使用ssh隧道连接mysql的操作
Dec 05 Python
python 自定义异常和主动抛出异常(raise)的操作
Dec 11 Python
python自动化发送邮件实例讲解
Jan 04 Python
tensorflow输出权重值和偏差的方法
Feb 10 #Python
详解tensorflow实现迁移学习实例
Feb 10 #Python
Python学习之Django的管理界面代码示例
Feb 10 #Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
Feb 10 #Python
tensorflow训练中出现nan问题的解决
Feb 10 #Python
用Eclipse写python程序
Feb 10 #Python
tensorflow建立一个简单的神经网络的方法
Feb 10 #Python
You might like
java EJB 加密与解密原理的一个例子
2008/01/11 PHP
PHP 下载文件时自动添加bom头的方法实例
2014/01/10 PHP
PHP代码优化之成员变量获取速度对比
2014/02/28 PHP
PHP实现文件下载断点续传详解
2014/10/15 PHP
php格式化电话号码的方法
2015/04/24 PHP
PHP中非常有用却鲜有人知的函数集锦
2019/08/17 PHP
Yii 框架入口脚本示例分析
2020/05/19 PHP
jQuery live( type, fn ) 委派事件实现
2009/10/11 Javascript
纯js代码实现简单计算器
2015/12/02 Javascript
分享JavaScript监听全部Ajax请求事件的方法
2016/08/28 Javascript
如何给ss bash 写一个 WEB 端查看流量的页面
2017/03/23 Javascript
JS简单判断滚动条的滚动方向实现方法
2017/04/28 Javascript
jQuery使用JSONP实现跨域获取数据的三种方法详解
2017/05/04 jQuery
跨域解决之JSONP和CORS的详细介绍
2018/11/21 Javascript
原生JS检测CSS3动画是否结束的方法详解
2019/01/27 Javascript
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
2019/02/20 Javascript
微信小程序模板消息推送的两种实现方式
2019/08/27 Javascript
微信小程序自定义波浪组件使用方法详解
2019/09/21 Javascript
在vue中把含有html标签转为html渲染页面的实例
2019/10/28 Javascript
vue-cli4.x创建企业级项目的方法步骤
2020/06/18 Javascript
html5以及jQuery实现本地图片上传前的预览代码实例讲解
2021/03/01 jQuery
[04:44]DOTA2英雄梦之声_第12期_矮人直升机
2014/06/21 DOTA
Eclipse + Python 的安装与配置流程
2013/03/05 Python
Python中常用信号signal类型实例
2018/01/25 Python
用Python分析3天破10亿的《我不是药神》到底神在哪?
2018/07/12 Python
opencv实现图片模糊和锐化操作
2018/11/19 Python
python中logging模块的一些简单用法的使用
2019/02/22 Python
Python过滤掉numpy.array中非nan数据实例
2020/06/08 Python
Python selenium实现断言3种方法解析
2020/09/08 Python
Python操作dict时避免出现KeyError的几种解决方法
2020/09/20 Python
欧洲著名的珠宝和手表网上商城:uhrcenter
2017/04/10 全球购物
Clarks其乐鞋荷兰官网:Clarks荷兰
2019/07/05 全球购物
益模软件Java笔试题
2012/03/27 面试题
求职者应聘的自我评价
2013/10/16 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
入党积极分子评语
2014/05/04 职场文书