霍夫直线

 

示例代码:

         Mat src, src_gray, dst;
	src = imread("D:/vcprojects/images/lines.png");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}

	char INPUT_TITLE[] = "input image";
	char OUTPUT_TITLE[] = "hough-line-detection";
	namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
	namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_TITLE, src);

	// extract edge
	Canny(src, src_gray, 150, 200);
	cvtColor(src_gray, dst, CV_GRAY2BGR);
	imshow("edge image", src_gray);

	vector<Vec2f> lines;     
	HoughLines(src_gray, lines, 1, CV_PI / 180, 150, 0, 0);
	for (size_t i = 0; i < lines.size(); i++) { 
		float rho = lines[i][0]; // 极坐标中的r长度
		float theta = lines[i][1]; // 极坐标中的角度
		Point pt1, pt2;         
		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(dst, pt1, pt2, Scalar(0, 0, 255), 1, CV_AA); 
	}

	/*
	vector<Vec4f> plines;
	HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 10, 0, 10);
	Scalar color = Scalar(0, 0, 255);
	for (size_t i = 0; i < plines.size(); i++) {
		Vec4f hline = plines[i];
		line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 3, LINE_AA);
	}*/
	imshow(OUTPUT_TITLE, dst);

程序结果:

import cv2 as cv import numpy as np #直线检测 #使用霍夫直线变换做直线检测,前提条件:边缘检测已经完成 #标准霍夫线变换 def line_detection(image): gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) edges = cv.Canny(gray, 50, 150) #apertureSize参数默认其实就是3 cv.imshow("edges", edges) #cv.HoughLines参数设置:参数1,灰度图像;参数二,以像素为单位的距离精度(一般都是1,进度高,但是速度会慢一点) #参数三,以弧度为单位的角度精度(一般是1rad);参数四,阈值,大于阈值threshold的线段才可以被检测通过并返回到结果中 #该函数返回值为rho与theta lines = cv.HoughLines(edges, 1, np.pi/180, 200) for line in lines: rho, theta = line[0] #line[0]存储的是点到直线的极径和极角,其中极角是弧度表示的。 a = np.cos(theta) #theta是弧度 b = np.sin(theta) x0 = a * rho #代表x = r * cos(theta) y0 = b * rho #代表y = r * sin(theta) x1 = int(x0 + 1000 * (-b)) #计算直线起点横坐标 y1 = int(y0 + 1000 * a) #计算起始起点纵坐标 x2 = int(x0 - 1000 * (-b)) #计算直线终点横坐标 y2 = int(y0 - 1000 * a) #计算直线终点纵坐标 注:这里的数值1000给出了画出的线段长度范围大小,数值越小,画出的线段越短,数值越大,画出的线段越长 cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) #点的坐标必须是元组,不能是列表。 cv.imshow("image-lines", image) #统计概率霍夫线变换 def line_detect_possible_demo(image): gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) edges = cv.Canny(gray, 50, 150, apertureSize=3) # apertureSize参数默认其实就是3 lines = cv.HoughLinesP(edges, 1, np.pi / 180, 60, minLineLength=60, maxLineGap=5) for line in lines: x1, y1, x2, y2 = line[0] cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) cv.imshow("line_detect_possible_demo",image) src = cv.imread("E:/opencv/picture/track.jpg") print(src.shape) cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE) cv.imshow('input_image', src) line_detection(src) src = cv.imread("E:/opencv/picture/track.jpg") #调用上一个函数后,会把传入的src数组改变,所以调用下一个函数时,要重新读取图片 line_detect_possible_demo(src) cv.waitKey(0) cv.destroyAllWindows() 霍夫检测直线原理: 关于hough变换,核心以及难点就是关于就是有原始空间到参数空间的变换上。以直线检测为例,假设有一条直线L,原点到该直线的垂直距离为p,垂线与x轴夹角为θθ,那么这条直线是唯一的,且直线的方程为 ρ=xcosθ+ysinθρ=xcosθ+ysinθ, 如下图所
### 如何使用 Python 和 OpenCV 实现霍夫直线检测 霍夫变换是一种用于从图像中提取几何形状的技术,在计算机视觉领域广泛应用。通过 OpenCV 的 `cv2.HoughLines` 或 `cv2.HoughLinesP` 函数可以轻松实现霍夫直线检测。 以下是完整的代码示例及其解释: #### 1. 导入必要的库 为了执行霍夫直线检测,需要导入 OpenCV 库以及其他辅助工具。 ```python import cv2 import numpy as np import matplotlib.pyplot as plt ``` #### 2. 加载并预处理图像 加载原始图像后,通常将其转换为灰度图并通过 Canny 边缘检测器获取边缘信息。 ```python image = cv2.imread('input_image.jpg', cv2.IMREAD_COLOR) # 读取彩色图像 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转换为灰度图 edges = cv2.Canny(gray, 50, 150, apertureSize=3) # 使用Canny算子检测边缘 plt.imshow(edges, cmap='gray') # 显示边缘图像 ``` #### 3. 定义霍夫变换参数 设置霍夫变换的关键参数,包括距离分辨率 (`rho`)、角度分辨率 (`theta`) 和累加器阈值 (`threshold`)。 ```python rho = 1 # 距离分辨率 (以像素为单位) theta = np.pi / 180 # 角度分辨率 (以弧度为单位) threshold = 100 # 累加器阈值 参数越高则检测越严格 min_line_length = 50 # 最短有效线段长度 max_line_gap = 20 # 同一线允许的最大间隙 ``` #### 4. 执行概率霍夫变换 利用 `cv2.HoughLinesP` 方法来检测图像中的直线段。 ```python lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]), minLineLength=min_line_length, maxLineGap=max_line_gap) line_image = np.copy(image) # 创建一幅空白图像用于绘制检测到的线条 if lines is not None: for line in lines: for x1, y1, x2, y2 in line: cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 5) # 绘制蓝色直线 ``` #### 5. 展示结果 最后将原图像与检测到的直线叠加显示。 ```python result = cv2.addWeighted(image, 0.8, line_image, 1, 0) # 将原图与线条图融合 plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB)) # 显示最终结果 plt.show() ``` 以上过程展示了如何使用 OpenCV 中的概率霍夫变换方法完成直线检测任务[^1]。 --- ### 关键点解析 - **Canny 边缘检测** 是霍夫变换前的一个重要步骤,它能够显著减少背景干扰并突出潜在的直线区域[^3]。 - **累积投票机制** 是霍夫变换的核心原理,即使存在噪声或部分缺失数据也能鲁棒地识别目标形状[^2]。 - **调整参数** 对于获得理想效果至关重要;例如增大 `rho` 和 `theta` 值可提高灵敏度,而提升 `threshold` 则有助于过滤虚假正样本[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值