opencv 霍夫直线检测

    熟悉的opencv 又回到我的博客了,接下来带大家最简单的方式来理解对应原理,然后是如何处理的。

     霍夫(Hough)变换是一个非常重要的检查间断点边形状的方法 ,它通过将图像坐标空间变换到参数空间,来实现直线和曲线的拟合。

霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。

霍夫直线检测  

 效果图。 

基本理论:

平面空间(空域)到极坐标空间(霍夫空间)转换

一条直线在图像二维空间可由两个变量表示。 

 在极坐标变换:

 通过转换就可以变成:

 我们原来的直线可以变成下面:

当我们给定x,y值。  我们以θ与r可以知道是个正弦函数。

然后我们通过不同的x,y 值可以画出多少 

 相交的一点可以证明,对应的θ与r,这些多点的x,y值,满足

 这个直线方程,从而证明,他们的数据在这个直线上,是不是非常简单。

有关的Api 是有两个:一个被称为标准霍夫变换直线检测,另外一个叫霍夫直线检测。二者之间的区别在于,前者会直接输出theta与r,还有累加和,后者会直接输出相关线段的平面坐标。

 标准霍夫变换直线检测

void cv::HoughLines(
    InputArray image, // 输入参数
    OutputArray lines, // 输出结果vector<Vec2f>, vector<Vec3f>
    double rho, // 距离步长d=1, 是指该直线到原点距离,对于屏幕坐标是左上角点
    double theta, // 角度步长1°
    int threshold, // 阈值,是指累加数目
    double srn = 0, // 多尺度检测需要,默认为0
    double stn = 0, // 多尺度检测需要,默认为0
    double min_theta = 0, // 直线旋转角度
    double max_theta = CV_PI // 直线旋转角度
)

 对输出的结果是Vec2f的话为(r, theta)如果是Vec3f的话为(r, theta, votes)。

 霍夫直线检测

HoughLinesP(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线
double rho, // 生成极坐标时候的像素扫描步长,一般取1
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线,可以写10
double minLineLength=0;// 最小直线长度
double maxLineGap=0;// 两交点间允许的最大间隔,(经canny的梯度可能不连续,间隔调大)
)

 程序代码:

// hoffLine.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace std;
using namespace cv;
int main()
{
	Mat src, dst;

	src = imread("D:/图片/马路.jpg");
	if (!src.data)
	{
		cout << "不能加载数据" << endl;
	}
	char input_title[] = "input image";
	char output_title[] = "hough-line-detection";
	namedWindow(input_title, CV_WINDOW_AUTOSIZE);
	imshow(input_title, src);
	Mat gray_src;
	Canny(src, gray_src, 150, 200);
	cvtColor(gray_src, dst, CV_GRAY2BGR);
	imshow("edge image", gray_src);

	//开始霍夫变换
	vector<Vec2f> lines;
	HoughLines(gray_src, 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 = rho*a, y0 = rho*b;
		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(gray_src, plines, 1, CV_PI / 180.0, 10, 30, 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, 2, LINE_AA);
	//}
	imshow(output_title, dst);
	waitKey(0);
    return 0;
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值