霍夫变换常用来在图像中提取直线和圆等几何形状。如下图:

我们下面来看看如何使用霍夫变换来检测直线。一条直线可以用数学表达式 y = mx + 或者 ρ = xcosθ + y sinθ表示(极坐标)

简单说明一下:

ρ 是从原点到直线的垂直距离,θ是直线的垂线与横轴顺时针方向的夹角,如下图所示:

首先创建一个2D数组(累加器),初始化累加器,所有的值都为0。行表示 ρ,列表示 θ。这个数组的大小决定了最后结果的准确性。如果你希望角度精确到1°,你就需要180列。对于 ρ,最大值为图片对角线距离。

想象一下我们有一个大小为100x100的直线位于图像中央。取直线上的第一个点,我们知道此处的(x,y)值,把x和y带入公式:ρ = xcosθ + y sinθ,然后遍历 θ 的取值0, 1, 2, 3,...,180.分别求出对应的 ρ 值,这样我们就得到了一系列(ρ,θ)的数值对,如果这个数值对在累加器中也存在相应的位置,就在这个位置上加 1。由于同一条直线上的点必然会有同样的(ρ,θ)。所以现在累加器中的(50,90)=1。现在取直线上的第二个点。重复上边的过程。更新累加器中的值。现在累加器中(50,90)的值为 2。你每次做的就是更新累加器中的值。对直线上的每个点都执行上边的操作,每次操作完成之后,累加器中的值就加 1,但其他地方有时会加 1, 有时不会。按照这种方式下去,到最后累加器中(50,90)的值肯定是最大的。如果你搜索累加器中的最大值,并找到其位置(50,90),这就说明图像中有一条直线,这条直线到原点的距离为 50,它的垂线与横轴的夹角为 90 度。

OpenCV中首先计算(r,θ) 累加数,累加数超过一定值后就认为在同一直线上(有一个阈值)。

霍夫直线变换

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_BGR2GRAY)
edges = cv2.Canny(gray, , )
# .霍夫直线变换
lines = cv2.HoughLines(edges, 0.8, np.pi / , )

函数中:

  • 参数1:要检测的二值图(一般是阈值分割或边缘检测后的图)
  • 参数2:距离 ρ 的精度,值越大,考虑越多的线
  • 参数3:角度 θ 的精度,值越小,考虑越多的线
  • 参数4:累加数阈值,值越小,考虑越多的线
# .将检测的线画出来(注意是极坐标噢)
for line in lines:
rho, theta = line[]
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + * (-b))
y1 = int(y0 + * (a))
x2 = int(x0 - * (-b))
y2 = int(y0 - * (a))
cv2.line(drawing, (x1, y1), (x2, y2), (, , ))

统计概率霍夫直线变换

前面的方法又称为标准霍夫变换,它会计算图像中的每一个点,计算量比较大,另外它得到的是整一条线,并不知道原图中直线的端点。所以提出了概率霍夫直线变换(Probabilistic Hough Transform),是一种改进的霍夫变换:

drawing = np.zeros(img.shape[:], dtype=np.uint8)
# 统计概率霍夫线变换
lines = cv2.HoughLinesP(edges, 0.8, np.pi / , , minLineLength=, maxLineGap=)

# 将检测的线画出来
for line in lines:
x1, y1, x2, y2 = line[]
cv2.line(drawing, (x1, y1), (x2, y2), (, , ), , lineType = cv2.LINE_AA)
cv2.imwrite('houghlines4.jpg', drawing)

参数:

  • minLineLength:最短长度阈值,比这个长度短的线会被排除
  • maxLineGap:同一直线两点之间的最大距离

cv2.LINE_AA:抗锯齿线型

霍夫圆变换

霍夫圆变换跟直线变换类似,只不过线是用(r,θ),圆是用(x_center,y_center,r)来表示,从二维变成了三维,数据量变大了很多;所以一般使用霍夫梯度法去减少计算量

drawing = np.zeros(img.shape[:], dtype=np.uint8)
# 霍夫圆变换
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, , , param2=)
circles = np.int0(np.around(circles)) # 将检测的圆画出来
for i in circles[, :]:
cv2.circle(drawing, (i[], i[]), i[], (, , ), ) # 画出外圆
cv2.circle(drawing, (i[], i[]), , (, , ), ) # 画出圆心
cv2.imwrite('HoughCircles.jpg', drawing)
  • 参数2:变换方法,一般使用霍夫梯度法,详情:HoughModes
  • 参数3 dp=1:表示霍夫梯度法中累加器图像的分辨率与原图一致
  • 参数4:两个不同圆圆心的最短距离
  • 参数5:param2跟霍夫直线变换中的累加数阈值一样

OpenCV-Python:霍夫变换的更多相关文章

  1. OpenCV Python教程(3、直方图的计算与显示)

    转载请详细注明原作者及出处,谢谢! 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途什么的就直接略过去了. ...

  2. OpenCV + python 实现人脸检测(基于照片和视频进行检测)

    OpenCV + python 实现人脸检测(基于照片和视频进行检测) Haar-like 通俗的来讲,就是作为人脸特征即可. Haar特征值反映了图像的灰度变化情况.例如:脸部的一些特征能由矩形特征 ...

  3. opencv+python视频实时质心显示

    利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...

  4. Erlang/Elixir: 使用 OpenCV, Python 搭建图片缩略图服务器

    这篇文章是在OSX上测试和运行的的, Ubuntu下的安装和配置请移步到这里 应用程序进程树, 默认 Poolboy 中初始化10个用于处理图片的 Python 工作进程(Worker) 首先安装Op ...

  5. opencv python实用操作

    画多边形 fillConvexPloy与fillConvexPloy的区别 fillConvexPloy 用来画单个凸多边形: 如果点集的连线不是凹多边形,则会找一个最小的凸多边形把该凹多边形包住画出 ...

  6. Win7 64bit+Anaconda(3-5.0.1,Python3.6)+Pycharm(community-2017.3.3)+OpenCV(python‑3.4.0‑cp36‑cp36m)(转载)

    Anaconda(3-5.0.1,Python3.6)下载链接:https://pan.baidu.com/s/1bqFwLMB 密码:37ih Pycharm(community-2017.3.3) ...

  7. 解决Windows Server 2012 R2 Datacenter云服务器无法运行opencv python程序的问题

    写了个基于opencv的python程序,pyinstaller 32位机打包后在win7/win10 32/64正常运行,在Windows Server 2012 R2 Datacenter云服务器 ...

  8. OpenCV Python 4.0安装

    1.安装OpenCV-Python 如果你是第一次使用OpenCV Python开发包,想要安装OpenCV Python4.0只要执行如下命令行即可: pip install opencv-pyth ...

  9. Ubuntu系统---安装Caffe (+OpenCV+Python+CPU-only)

    安装配置Ubuntu14.04+Caffe (+OpenCV+Python+CPU-only) 记录 [作者:Wu Ping.时间:20180428.] 本人已经安装很多次的Caffe了:从开始的初探 ...

  10. Linux下安装OpenCV+Python支持

    以下说明在Linux下Python和OpenCV结合安装的过程,Python要使用OpenCV模块,则必须导入OpenCV提供的包,所以要提供Python支持,首先在安装OpenCV前安装必要的组件, ...

随机推荐

  1. python并发编程之协程知识点

    由线程遗留下的问题:GIL导致多个线程不能真正的并行,CPython中多个线程不能并行 单线程实现并发:切换+保存状态 第一种方法:使用yield,yield可以保存状态.yield的状态保存与操作系 ...

  2. CF350E 【Wrong Floyd】

    Description 给定n个点,m条边,k个标记点,hack掉给出的程序. Solution 先考虑不可能hack掉的情况.当所有点都是标记点的时候肯定不能hack掉,也就是\(n=k\).还有就 ...

  3. 第四十一篇-android studio 关闭自动保存功能

    此方法不可用. 第一步:取消自动保存功能 File > Settings > Appearance & Behavior > System Settings > Syn ...

  4. java的集合:List、Set和Map

    虚线是接口,实线是实现类: 集合能够解决的问题:集合可以丽杰为是一种更高级的数组,可以保存多条数据 本质:java官方开发人员基于java的一些基础内容(数组等等)创建了一些接口和类,然后使用这些接口 ...

  5. Git的相关知识

    什么是git        Git(读音为/gɪt/.)是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理.Git 是 Linus Torvalds 为了帮助管理 Lin ...

  6. redis connection refused: connect 启动失败

    先到redis解压包下执行 ./redis-server redis.conf 再连接 redis-cli

  7. 0. Java虚拟机系列备忘预览图

    打算把Java虚拟机这块单独弄一个主题出来,做做备忘,结构如图所示: 后面还有一部分待更新...

  8. SVG---DEMO

    SVG代码: <svg id="circle" data-name="circle_1" xmlns="http://www.w3.org/20 ...

  9. HBase LSM树存储引擎详解

    1.前提 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎. B树存储引擎. LSM树(Log-Structured Merge Tree)存储引擎. 2. 哈希 ...

  10. 线段树——习题、lazy解析

    习题: C. Cloud Computing lazy操作解析: