Python OpenCV中的霍夫线变换(Hough Line Transform)详解
文章目录
更多有趣的代码示例,可参考【Programming】
1、功能描述
基于 opencv-python 使用 hough 变换(cv2.HoughLines、cv2.HoughLinesP),来检测出来图片中的直线
2、原理分析
参考 Hough变化
图像空间中的每条直线在参数空间中都对应着单个点;在图像空间中直线上的任何像素在参数空间中对应的直线(曲线)相交于同一个点。因此,通过Hough变换寻找图像中的直线就是寻找参数空间中大量直线(曲线)相交的一点。
3、代码实现
导入必要的库函数
import sys
import math
import cv2 as cv
import numpy as np
写好程序入口
if __name__ == "__main__":
main(sys.argv[1:], save=True)
读入图片,转成灰度图
def main(argv, save=False):
default_file = '1.jpg'
filename = argv[0] if len(argv) > 0 else default_file
# Loads an image
src = cv.imread(cv.samples.findFile(filename))
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
确认图片是否载入成功
# Check if image is loaded fine
if src is None:
print('Error opening image!')
print('Usage: hough_lines.py [image_name -- default ' + default_file + '] \n')
return -1
canny 变化准备提取边缘(潜在直线区域)
dst = cv.Canny(gray, 50, 200, None, 3)
if save:
cv.imwrite("canny.jpg", dst)
复制图片,以备绘制两种 hough 算法的结果
cdst = np.copy(src)
cdstP = np.copy(src)
调用 cv2.HoughLines
,求出图片中的直线,并绘制出来
lines = cv.HoughLines(dst, 1, np.pi / 180, 150, None, 0, 0)
if lines is not None:
for i in range(0, len(lines)):
rho = lines[i][0][0]
theta = lines[i][0][1]
a = math.cos(theta)
b = math.sin(theta)
x0 = a * rho
y0 = b * rho
pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * (a)))
pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * (a)))
cv.line(cdst, pt1, pt2, (0, 0, 255), 1, cv.LINE_AA)
调用 cv2.HoughLinesP
,求出图片中的直线,并绘制出来
linesP = cv.HoughLinesP(dst, 1, np.pi / 180, 50, None, 50, 10)
if linesP is not None:
for i in range(0, len(linesP)):
l = linesP[i][0]
cv.line(cdstP, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv.LINE_AA)
绘制的时候会更宽一些,cv.line(cdstP, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv.LINE_AA)
配置为了 3
显示原图及两种方法绘制出来直线的效果,保存结果,退出显示,退出主程序
cv.imshow("Source", src)
cv.imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst)
cv.imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP)
if save:
cv.imwrite("cdst.jpg", cdst)
cv.imwrite("cdstP.jpg", cdstP)
cv.waitKey()
return 0
4、效果展示
会依赖于 canny 算子的
5、完整代码
"""
@file hough_lines.py
@brief This program demonstrates line finding with the Hough transform
"""
import sys
import math
import cv2 as cv
import numpy as np
def main(argv, save=False):
default_file = '2.jpg'
filename = argv[0] if len(argv) > 0 else default_file
# Loads an image
src = cv.imread(cv.samples.findFile(filename))
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
# Check if image is loaded fine
if src is None:
print('Error opening image!')
print('Usage: hough_lines.py [image_name -- default ' + default_file + '] \n')
return -1
dst = cv.Canny(gray, 50, 200, None, 3)
if save:
cv.imwrite("canny.jpg", dst)
cdst = np.copy(src)
cdstP = np.copy(src)
lines = cv.HoughLines(dst, 1, np.pi / 180, 150, None, 0, 0)
if lines is not None:
for i in range(0, len(lines)):
rho = lines[i][0][0]
theta = lines[i][0][1]
a = math.cos(theta)
b = math.sin(theta)
x0 = a * rho
y0 = b * rho
pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * (a)))
pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * (a)))
cv.line(cdst, pt1, pt2, (0, 0, 255), 1, cv.LINE_AA)
linesP = cv.HoughLinesP(dst, 1, np.pi / 180, 50, None, 50, 10)
if linesP is not None:
for i in range(0, len(linesP)):
l = linesP[i][0]
cv.line(cdstP, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv.LINE_AA)
cv.imshow("Source", src)
cv.imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst)
cv.imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP)
if save:
cv.imwrite("cdst.jpg", cdst)
cv.imwrite("cdstP.jpg", cdstP)
cv.waitKey()
return 0
if __name__ == "__main__":
main(sys.argv[1:], save=True)
6、涉及到的库函数
cv2.HoughLines
cv2.HoughLines
是 OpenCV 中用于霍夫直线变换的函数,它能够在图像中检测直线。
一、函数原型
lines = cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]])
二、参数说明
三、返回值
四、使用示例
import cv2
import numpy as np
# 读取图像
image = cv2.imread('example_image.jpg')
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用 Canny 边缘检测
edges = cv2.Canny(gray, 50, 150)
# 使用霍夫变换检测直线
lines = cv2.HoughLines(edges, 1, np.pi / 180, 150)
# 绘制检测到的直线
if lines is not None:
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(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
# 显示结果图像
cv2.imshow('Detected Lines', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
五、注意事项
cv2.HoughLinesP
cv2.HoughLinesP
是 OpenCV 中用于概率霍夫线变换(Probabilistic Hough Transform)的函数,相比于标准的霍夫线变换(cv2.HoughLines),它能够在保持检测效果的同时显著减少计算量。
一、函数原型
lines = cv2.HoughLinesP(image, rho, theta, threshold, minLineLength, maxLineGap)
二、参数说明
三、返回值
四、使用示例
import cv2
import numpy as np
# 读取图像
image = cv2.imread('example_image.jpg')
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用 Canny 边缘检测
edges = cv2.Canny(gray, 50, 150)
# 使用概率霍夫变换检测线段
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=10)
# 绘制检测到的线段
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
# 显示结果图像
cv2.imshow('Detected Lines', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
五、注意事项
7、参考
更多有趣的代码示例,可参考【Programming】
作者:bryant_meng