文章图片
什么是霍夫空间?Python OpenCV霍夫变换教程:在我们开始将霍夫变换应用于图像之前,我们需要了解霍夫空间是什么,我们将通过一个例子来学习。
参数空间
【Python OpenCV霍夫变换教程(如何理解和实现形状检测())】当我们处理图像时,我们可以将图像想象成一个在一些 x 和 y 坐标上的二维矩阵,在该矩阵下,一条线可以被描述为
y = mx + b
文章图片
m
vs相同的线b
,因此图像空间上线的表征将是m-b
霍夫空间中位置处的单个点。文章图片
y = mx + b
,我们不能表示一条垂直线,因为斜率是无限的。所以我们需要一种更好的参数化方式,极坐标(rho 和 theta)。霍夫空间
- rho:描述线距原点的距离
- theta:描述远离水平线的角度
文章图片
文章图片
这将是我们的目标,找到一组曲线相交的点。
什么是霍夫变换?霍夫变换是一种特征提取方法,用于检测图像中的圆形、线条等简单形状。
“简单”特征是通过参数的形状表示得出的。一个“简单”的形状只会用几个参数来表示,例如一条直线可以用它的斜率和截距来表示,或者一个圆可以用 x、y 和半径来表示。
如何使用霍夫变换实现形状检测?在我们的线条示例中,霍夫变换将负责处理图像上的点并计算霍夫空间中的值。
进行转换并随后找到相交曲线的算法有点复杂,因此超出了本文的范围。然而,我们将看看这个算法的一个实现,它是OpenCV 库的一部分。
Python OpenCV霍夫变换教程:使用 OpenCV 检测线条在 OpenCV 中,使用霍夫变换的线检测是在函数
HoughLines
和HoughLinesP
(概率霍夫变换)中实现的。我们将专注于后者。该函数需要以下参数:
image
: 8 位单通道二进制源图像。图像可以被函数修改。lines
: 线的输出向量。每条线由一个 4 元素向量 (x_1, y_1, x_2, y_2) 表示,其中 (x_1,y_1) 和 (x_2, y_2) 是每个检测到的线段的终点。rho
:累加器的距离分辨率(以像素为单位)。theta
:以弧度为单位的累加器的角度分辨率。threshold
:累加器阈值参数。只返回那些获得足够选票的行minLineLength
: 最小线长。比它短的线段被拒绝。maxLineGap
:连接它们的同一条线上的点之间的最大允许间隙。
# Read image
img = cv2.imread('lanes.jpg', cv2.IMREAD_COLOR)
# Convert the image to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Find the edges in the image using canny detector
edges = cv2.Canny(gray, 50, 200)
# Detect points that form a line
lines = cv2.HoughLinesP(edges, 1, np.pi/180, max_slider, minLineLength=10, maxLineGap=250)
# Draw lines on the image
for line in lines:
x1, y1, x2, y2 = line[
0]
cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3)
# Show result
cv2.imshow("Result Image", img)
结果如下:
文章图片
Python OpenCV霍夫变换示例:使用 OpenCV 检测圆圈该过程与行的过程大致相同,不同之处在于这次我们将使用 OpenCV 库中的不同函数。我们将使用 now
HoughCircles
,它接受以下参数:image
: 8 位、单通道、灰度输入图像。circles
:找到的圆的输出向量。每个向量都被编码为一个 3 元素的浮点向量 (x, y, radius) 。circle_storage
: 在 C 函数中,这是一个内存存储,将包含找到的圆的输出序列。method
: 检测方法使用。目前唯一实现的方法是 CV_HOUGH_GRADIENT ,基本上是 21HTdp
: 累加器分辨率与图像分辨率的反比。例如,如果 dp=1 ,则累加器具有与输入图像相同的分辨率。如果 dp=2 ,累加器的宽度和高度是原来的一半。minDist
:检测到的圆的中心之间的最小距离。如果参数太小,除了一个真一个之外,可能还会错误地检测到多个邻居圆。如果太大,可能会遗漏一些圆圈。param1
:第一个特定于方法的参数。在 CV_HOUGH_GRADIENT 的情况下,它是传递给 Canny() 边缘检测器的两者中较高的阈值(较低的阈值小两倍)。param2
:第二个特定于方法的参数。在 CV_HOUGH_GRADIENT 的情况下,它是检测阶段圆心的累加器阈值。它越小,检测到的假圆就越多。与较大累加器值相对应的圆圈将首先返回。minRadius
:最小圆半径。maxRadius
:最大圆半径。
(x - x0)^^2 + (y - y0)^^2 = r^^2
.和代码:
# Read image as gray-scale
img = cv2.imread('circles.png', cv2.IMREAD_COLOR)
# Convert to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur the image to reduce noise
img_blur = cv2.medianBlur(gray, 5)
# Apply hough transform on the image
circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1, img.shape[
0]/64, param1=200, param2=10, minRadius=5, maxRadius=30)
# Draw detected circles
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[
0, :]:
# Draw outer circle
cv2.circle(img, (i[
0], i[
1]), i[
2], (0, 255, 0), 2)
# Draw inner circle
cv2.circle(img, (i[
0], i[
1]), 2, (0, 0, 255), 3)
请注意,与前面的示例相比,我们没有在此处应用任何边缘检测功能。这是因为该功能
HoughCircles
具有内置的智能检测功能。结果:
文章图片
谢谢阅读!
推荐阅读
- 前10名最佳Vuetify管理仪表板模板 – 免费和高级
- 5个经典JavaScript问题和答案来测试你的技能
- 如何使用Plotly和Python实现交互式数据可视化()
- 17个Python常见面试题和答案合集(面试必备)
- Node如何使用Elasticsearch(构建搜索引擎示例)
- 如何使用Electron构建桌面应用程序(分步指南)
- 如何使用NodeJS和AWS Lambda实现无服务器()
- Puppeteer和NodeJS如何将网页转换为PDF()
- Windows 8.1专业版降低硬盘读写频率的多种技巧