OpenCV中的霍夫线变换概率霍夫线变换
Posted 程序媛一枚~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV中的霍夫线变换概率霍夫线变换相关的知识,希望对你有一定的参考价值。
OpenCV中的霍夫线变换、概率霍夫线变换
这篇博客将介绍Python,OpenCV中的霍夫变换。包括什么是霍夫变换(Hough Transform)、概率霍夫变换(Probablistic Hough Transform),以及如何使用cv2.HoughLines(),cv2.HoughLinesP()来检测图像中的线条。
1. 效果图
原始图 VS霍夫变换效果图如下:
图中检测了所有线,包括角度为0°~180°(红色线,经过原点下方的点)和 角度为-180°~0°的(绿色线,经过原点上方的点)。
原图 VS 概率霍夫变换效果图如下:
概率霍夫变换效果可以设置线之间的间隙大小,检测出来小的短的线;
2. 原理
任意一条线可以用 y=mx+c 进行表示,也可用( ρ,θ)表示, ρ=xcosθ+ysinθ。ρ以像素为单位,θ以弧度为单位。
如果直线从原点下方经过,它的ρ为正,角度为(0,180);如果直线从原点上方经过,ρ为负,角度为(-180,0)。任何垂直线都是0度,水平线是90度。
2.1 什么是霍夫变换?
霍夫变换是一种流行的检测任何形状的技术,即使它是有些微损坏或轻微扭曲的,它也可以成功检测。
lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
- edges:输入图像(二值图像,因此在应用hough变换查找之前,先应用阈值或canny边缘检测)
- 1: ρ精度,ρ以像素为单位,θ以弧度为单位。
- np.pi/180:θ精度
- 200:阈值,假设检测线,表示被检测到的线的最短长度,低于200像素长度的将被丢弃;
- lines: 返回值(ρ,θ),ρ以像素为单位,θ以弧度为单位。
2.2 什么是概率霍夫变换?
概率霍夫变换(Probablistic Hough Transform)是霍夫变换(Hough Transform)的优化。
-
霍夫变换拿线的所有点参与计算,而概率霍夫变换只考虑点的一个随机子集,这对于线检测是足够的。
-
霍夫变换返回值是( ρ,θ),而概率霍夫变换直接返回线的端点更便于操作;
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength, maxLineGap)
- edages、1、np.pi/180 跟霍夫变换一致,分别为输入二值图像、ρ精度、θ精度
- minLineLength:最小线条长度。小于此长度的线将被丢弃;
- maxLineGap:直线段之间允许的最大间距,将其视为单线。
- lines:它直接返回线的俩个端点。
3. 源码
3.1 霍夫变换
# 霍夫变换(可检测任意形状)
# lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
# - edges:输入图像(二值图像,因此在应用hough变换查找之前,先应用阈值或canny边缘检测)
# - 1: ρ精度,ρ以像素为单位,θ以弧度为单位。
# - np.pi/100: 角度,θ精度
# - 200:阈值,假设检测线,表示被检测到的线的最短长度
# - lines: 返回值(ρ,θ),ρ以像素为单位,θ以弧度为单位。
#
# 概率霍夫变换(Probablistic Hough Transform)是霍夫变换(Hough Transform)的优化。
# 霍夫变换拿线的所有点参与计算,而概率霍夫变换不考虑所有的点,而是只考虑点的一个随机子集,这对于线检测是足够的。
# lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength, maxLineGap)
# - edages、1、np.pi/180 跟霍夫变换一致,分别为输入二值图像、ρ精度、θ精度
# - minLineLength:最小线条长度。小于此长度的线段将被丢弃;
# - maxLineGap:直线段之间允许的最大间距,将其视为单线。
# - lines:它直接返回两条线的端点。
import cv2
import imutils
import numpy as np
img = cv2.imread('hf1.jpg')
cv2.imshow("origin", imutils.resize(img, width=400))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
print(np.pi / 180, np.pi / 360)
lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
for i, line in enumerate(lines):
for rho, theta in line:
# print(rho, theta * 180 - 180)
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))
# 弧度转角度
degree = theta * 180 - 180
if (degree > 180):
degree = degree - 360
print(rho, degree)
if rho > 0 and degree > 0: # 经过原点下方的点,角度为正(0,180)
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
else: # 经过原点上方的点,角度为负(-180,0)
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.imwrite('houghlines_hf.jpg', img)
cv2.imshow("hf_res", imutils.resize(img, width=400))
cv2.waitKey(0)
3.2 概率霍夫变换
# 概率霍夫变换
# 霍夫变换(可检测任意形状)
# lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
# - edges:输入图像(二值图像,因此在应用hough变换查找之前,先应用阈值或canny边缘检测)
# - 1: ρ精度
# - np.pi/100:θ精度
# - 200:阈值,假设检测线,表示被检测到的线的最短长度
# - lines: 返回值(ρ,θ),ρ以像素为单位,θ以弧度为单位。
# 概率霍夫变换(Probablistic Hough Transform)是霍夫变换(Hough Transform)的优化。
# 霍夫变换拿线的所有点参与计算,而概率霍夫变换不考虑所有的点,而是只考虑点的一个随机子集,这对于线检测是足够的。
# lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength, maxLineGap)
# - edages、1、np.pi/180 跟霍夫变换一致,分别为输入二值图像、ρ精度、θ精度
# - minLineLength:最小线条长度。小于此长度的线段将被丢弃;
# - maxLineGap:直线段之间允许的最大间距,将其视为单线。
# - lines:它直接返回两条线的端点。
# 概率霍夫变换(Probablistic Hough Transform)是霍夫变换(Hough Transform)的优化。
# 霍夫变换拿线的所有点参与计算,而概率霍夫变换不考虑所有的点,而是只考虑点的一个随机子集,这对于线检测是足够的。
import cv2
import imutils
import numpy as np
img = cv2.imread('hf1.jpg')
cv2.imshow("origin", imutils.resize(img, width=400))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 10, minLineLength, maxLineGap)
# 只绘制第一条线
# for x1, y1, x2, y2 in lines[0]:
# cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
print(len(lines))
# 绘制所有检测结果
for i, line in enumerate(lines):
for x1, y1, x2, y2 in line:
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.imwrite('houghlines_hfp.jpg', img)
cv2.imshow("hfp_res", imutils.resize(img, width=400))
cv2.waitKey(0)
参考
以上是关于OpenCV中的霍夫线变换概率霍夫线变换的主要内容,如果未能解决你的问题,请参考以下文章