霍夫变换找直线python代码以及从极坐标到笛卡尔坐标的转换

图像霍夫变换找直线

霍夫变换(Hough Transform)是图像分析中用于检测几何形状(如直线、圆等)的方法。最常用的是直线检测的霍夫变换,它可以从霍夫空间(参数空间)到笛卡尔空间(图像空间)的转换关系中直观地理解。

在直线检测的应用中,霍夫变换考虑直线的参数方程形式 y = m x + b y = mx + b y=mx+b 或极坐标形式: x c o s ( θ ) + y s i n ( θ ) = ρ xcos(\theta) + ysin(\theta) = \rho xcos(θ)+ysin(θ)=ρ,其中 θ \theta θ是直线与x轴正方向的夹角, ρ \rho ρ是直线到原点的距离。在笛卡尔空间中,一条直线可以通过无数个点集来定义,而在霍夫空间中,这些点集映射为通过同一个点 ( ρ , θ ) (\rho, \theta) (ρ,θ)的曲线集合。换句话说,笛卡尔空间中一组共线的点在霍夫空间中对应一个交点。

下面的Python代码示例展示了如何使用OpenCV库实现霍夫变换来检测图像中的直线,并演示了霍夫空间与笛卡尔空间之间的转换关系:

可以通过以下代码进行直线检测:

import cv2
import numpy as np
from matplotlib import pyplot as plt

# 加载图像,并转换为灰度图
image = cv2.imread('path/to/your/image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 应用Canny边缘检测
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

# 使用霍夫变换检测直线
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)

# 在原图上绘制检测到的直线
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)

# 显示结果
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Detected Lines')
plt.axis('off')
plt.show()

从极坐标到斜率-截距的转换

在使用霍夫变换找到直线后,直线通常以极坐标形式的参数 ( ρ , θ ) (\rho, \theta) (ρ,θ) 表示,其中 ρ \rho ρ 是直线到原点的距离 θ \theta θ 是直线的法线与x轴正方向之间的角度。如果你想将这种表示转换为斜率-截距形式(即 (y = mx + b),其中 (m) 是斜率,(b) 是y轴截距),可以按照以下方法进行转换:
由极坐标方程 ( x c o s ( θ ) + y s i n ( θ ) = ρ ) (xcos(\theta) + ysin(\theta) = \rho) (xcos(θ)+ysin(θ)=ρ)出发,我们可以推导出直线的斜率 (m) 和截距 (b)。

斜率 m m m 的计算公式是:
m = − cos ⁡ ( θ ) sin ⁡ ( θ ) m = -\frac{\cos(\theta)}{\sin(\theta)} m=sin(θ)cos(θ)

截距 (b) 的计算公式是:
b = ρ sin ⁡ ( θ ) b = \frac{\rho}{\sin(\theta)} b=sin(θ)ρ

请注意,当 sin ⁡ ( θ ) = 0 \sin(\theta) = 0 sin(θ)=0(即 θ = 0 \theta = 0 θ=0 π \pi π 时,直线是垂直的,斜率 m 会是无限大,这种情况下斜率-截距表示不适用。

示例代码

以下是一个简单的Python示例,展示如何将霍夫变换检测到的直线转换为斜率-截距形式:

import numpy as np

# 假设有一条直线的极坐标参数 (rho, theta)
rho = 10
theta = np.pi / 6  # 30度

# 计算斜率 m 和截距 b
if np.sin(theta) != 0:
    m = -np.cos(theta) / np.sin(theta)
    b = rho / np.sin(theta)
else:
    m = np.inf  # 斜率无限大,表示直线垂直
    b = None

print(f"斜率: {m}, 截距: {b}")

这段代码将为你提供一个直线的斜率 (m) 和截距 (b),从而可以将直线在笛卡尔坐标系中以斜率-截距形式表示。如果直线垂直,斜率会被设置为无限大,这是数学上表示垂直直线的常用方式,而截距 (b) 在这种情况下没有定义。

  • 24
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值