实验三 霍夫变换直线检测实验
一、实验目的
- 掌握哈夫变换(Hough Transform)在图像处理中的基本原理。
- 学会使用计算机程序实现哈夫变换直线检测。
- 了解影响直线检测效果的参数,并学会调整这些参数以优化检测结果。
- 体会哈夫变换在实际场景(如边缘检测、道路检测等)中的应用。
二、实验内容和要求
1.实验内容:
- 选择一组图像用于哈夫变换直线检测实验。
- 使用计算机程序(如 Python 和 OpenCV)实现哈夫变换直线检测算法。
- 对图像进行预处理(如边缘检测)以提高直线检测效果。
- 调整哈夫变换的参数(如投票阈值、最小线段长度等),比较不同参数设置下的检测效果。
- 可视化和分析直线检测结果,通过图像展示检测到的直线。
2.基本要求:
- 编写哈夫变换直线检测程序,并能够对给定图像进行检测。
- 熟悉哈夫变换的参数及其对检测结果的影响,并能对不同参数设置下的检测结果进行分析。
- 对比不同图像和参数设置下的检测效果,进行详细分析并撰写实验报告。
三、实验设备
实验设备主要有:计算机、OpenCV库
四、实验原理
霍夫直线检测就是把图像空间中的直线变换到参数空间中的点,通过统计特性来解决检测问题。具体来说,如果一幅图像中的像素构成一条直线,那么这些像素坐标值(x, y)在参数空间对应的曲线一定相交于一个点,所以我们只需要将图像中的所有像素点(坐标值)变换成参数空间的曲线,并在参数空间检测曲线交点就可以确定直线了。
在理论上,一个点对应无数条直线或者说任意方向的直线(在参数空间中坐标轴表示的斜率k或者说θ有无数个),但在实际应用中,我们必须限定直线的数量(即有限数量的方向)才能够进行计算。
因此,我们将直线的方向θ离散化为有限个等间距的离散值,参数ρ也就对应离散化为有限个值,于是参数空间不再是连续的,而是被离散量化为一个个等大小网格单元。将图像空间(直角坐标系)中每个像素点坐标值变换到参数空间(极坐标系)后,所得值会落在某个网格内,使该网格单元的累加计数器加1。当图像空间中所有的像素都经过霍夫变换后,对网格单元进行检查,累加计数值最大的网格,其坐标值(ρ0, θ0)就对应图像空间中所求的直线。如图所示,为一个离散化过程。
霍夫变换直线检测步骤示例
五、实验步骤
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
#二值化图像(Canny边缘检测)
src = cv.imread("C:\\Users\\aslon\\Pictures\\Saved Pictures\\tizi.png")
img = src.copy()
# 二值化图像(Canny边缘检测)
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
dst_img = cv.Canny(gray_img, 50, 150)
# 霍夫线变换
lines = cv.HoughLines(dst_img, 2, np.pi / 180, 300)
# 将检测的线绘制在原图上
for line in lines:
rho, theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
# 找两个点
x0 = rho * a
y0 = rho * b
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * a)
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * a)
cv.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3)
# 显示图像
plt.subplot(311), plt.imshow(src, 'gray'), plt.title('src_img'), plt.axis('off')
plt.subplot(312), plt.imshow(dst_img, 'gray'), plt.title('canny_img'), plt.axis('off')
plt.subplot(313), plt.imshow(img, 'gray'), plt.title('HoughLines_img'), plt.axis('off')
plt.show()
待检测的图片为:
设置阈值分别为0.5,1,2,3时检测结果如下:
六、实验总结
- Hough 变换的参数设置会影响直线检测的结果。例如,`rho`和`theta`的分辨率、阈值等参数需要根据图像的大小和直线的特征进行调整。
- Hough 变换对噪声比较敏感,因此在进行直线检测之前,可以对图像进行预处理,如降噪、边缘增强等,以提高直线检测的准确性。
- Hough 变换可以检测出图像中的多条直线,但可能会出现误检测的情况。可以通过设置更高的阈值或使用其他方法来筛选出真正的直线。