OpenCV3图像处理——霍夫曼变换直线检测

前言

1.直线检测在好多实现应用中能用到到,我之前做过扫描件检测时用直线检测来处理判断页面是否水平,还有在辅助驾驶中的车道偏离预警系统也有过应用。
2.我的编程环境是Windows 7 64位,IDE是VS2015,配置了OpenCV3.3与OpenCV_Contrib,实现语言是C++。是于如果配置以上的环境,可以看我之前写的博文。

一、概述

1.直线检测的原理介绍
(1)对于直角坐标系中的任意一点A(x0,y0),经过点A的直线满足Y0=kX0+b.(k是斜率,b是截距)。
(2)那么在X-Y平面过点A(x0,y0)的直线簇可以用Y0=k
X0+b表示,但对于垂直于X轴的直线斜率是无穷大的则无法表示。因此将直角坐标系转换到极坐标系就能解决该特殊情况。
(3)在极坐标系中表示直线的方程为ρ=xCosθ+ySinθ(ρ为原点到直线的距离)。
在这里插入图片描述在这里插入图片描述
(4)对于任意一条直线上的所有点来说,变换到极坐标中,从[0~360]空间,可以得到r的大小,属于同一条直线上点在极坐标空(r, theta)必然在一个点上有最强的信号出现,根据此反算到平面坐标中就可以得到直线上各点的像素坐标。从而得到直线。
在这里插入图片描述
2.OpenCV封装有直线检测的函数,HoughLines()和HoughLinesP(),它们都能实现直线检测,差别是:HoughLines()函数使用标准的Hough变换HoughLinesP()函数使用概率Hough变换,即只通过分析点的子集并估计这些点都属于一条直线的概率,这在计算速度上更快。
(1)HoughLines()函数说明:
HoughLines(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线
double rho, // 生成极坐标时候的像素扫描步长
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double srn = 0;// 是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换
double stn = 0;//是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换
double min_theta = 0; // 表示角度扫描范围 0 ~180之间, 默认即可
double max_theta = CV_PI
)
(2)HoughLinesP()函数说明:
HoughLinesP(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线
double rho, // 生成极坐标时候的像素扫描步长
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double minLineLength = 0;// 最小直线长度
double maxLineGap = 0;// 最大间隔
)

二、代码演示

1.传入一张图像,把所有直线画出来。

void lineDetection(cv::Mat &cv_src, cv::Mat &cv_dst)
{
	cv::Mat cv_gray;

	cv_dst = cv_src.clone();
	
	//灰度化
	cvtColor(cv_dst, cv_gray, cv::COLOR_BGR2GRAY);

	cv::Mat cv_canny;
	Canny(cv_gray, cv_canny, 150, 200);

	std::vector<cv::Vec2f> lines;
	//霍夫曼直线检测
	cv::Point pt1, pt2;
	HoughLines(cv_canny, lines, 1, CV_PI / 180, 150, 0, 0);
	for (size_t i = 0; i < lines.size(); i++)
	{
		// 极坐标中的r长度
		float rho = lines[i][0];
		// 极坐标中的角度
		float theta = lines[i][1];
		double a = cos(theta), b = sin(theta);
		double x0 = a * rho, y0 = b * rho;
		// 转换为平面坐标的四个点
		pt1.x = cvRound(x0 + 1000 * (-b));
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 - 1000 * (-b));
		pt2.y = cvRound(y0 - 1000 * (a));
		line(cv_dst, pt1, pt2, cv::Scalar(0, 0, 255), 1, cv::LINE_AA);
	}
}

2.运行结果
在这里插入图片描述

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在Python和OpenCV中实现直线检测,可以使用Hough变换检测线Hough变换是一种常用的图像处理方法,可用于检测线、圆等几何形状。 以下是一个简单的示例代码,使用Hough变换检测线并计算交点: ```python import cv2 import numpy as np # 读取图像 img = cv2.imread('test.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 边缘检测 edges = cv2.Canny(gray, 50, 150, apertureSize=3) # Hough变换检测线 lines = cv2.HoughLines(edges, 1, np.pi/180, 200) # 计算交点 points = [] for i in range(len(lines)): for j in range(i+1, len(lines)): rho1, theta1 = lines[i][0] rho2, theta2 = lines[j][0] if abs(theta1 - theta2) < np.pi/4: continue a = np.array([[np.cos(theta1), np.sin(theta1)], [np.cos(theta2), np.sin(theta2)]]) b = np.array([rho1, rho2]) x0, y0 = np.linalg.solve(a, b) points.append((int(x0), int(y0))) # 绘制直线和交点 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(img, (x1,y1), (x2,y2), (0,0,255), 2) for point in points: cv2.circle(img, point, 5, (0,255,0), -1) # 显示图像 cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在代码中,首先读取图像并进行灰度转换和边缘检测。然后使用Hough变换检测线,并计算交点。最后绘制直线和交点,并显示图像。 需要注意的是,在计算交点时,需要将两条直线的极坐标表示转换为直角坐标表示,并使用线性方程组求解。 希望这个例子能够帮助到你实现直线检测并计算交点。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知来者逆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值