opencv图像处理学习(三十一)——霍夫变换

霍夫变换是从图像中识别几何形状的基本图像处理方法之一,经典的霍夫变换用来检测图像中的直线、改进的霍夫变换扩展到识别任意形状的物体。霍夫变换不受图形旋转的影响,易于进行几何图形的快速变换。

经典的霍夫变换用于检测图像中的直线,其原理是利用坐标空间变换将两个坐标进行相应转换,或通过直线映射到另一坐标空间的点形成的峰值,从而把检测任意形状的问题转化为统计峰值的问题。其突出优点是分割结果的鲁棒性,其缺点是要求知道物体边界线的解析方程。

以直线检测为例,每个像素坐标点经过空间变换都变成对直线特质有贡献的统一度量。对于二维图像数据f(x,y),平面坐标为(x,y),极坐标为(r,\theta),其中r是距原点坐标(0,0)的距离,\theta是直线垂线与x轴的夹角。

根据极坐标直线表达式可以看出,图像中一条直线是一系列离散像素点的几何,进而可以得到图像中直线极坐标的表达式:

xcos\theta +ysin\theta =r

对于图像像素平面坐标(x,y),我们需要做的就是通过空间坐标映射关系,将图像笛卡尔坐标系统转换到极坐标霍夫变换空间系统,这种点到曲线的映射变换称为霍夫变换。

<1>线检测技术

霍夫线变换是基于图像二值化的变换,利用二值化图像中的点集来确定候选直线集合。根据上节中的论述,在图像中的边界处,可以用f(x,p)=0来表示任意的曲线,其中p为曲线的参数向量,那么利用霍夫变换进行线检测算法的步骤如下:

(1)在参数p的范围内量化参数空间,将霍夫空间坐标(r,\theta)初始化为0

(2)在阈值化后的梯度图像中,对每个图像点(i,j)进行遍历,对于满足参数p,加权累计所有满足f(x,p)=0的单位S(p),则S(p)=S(p)+\bigtriangleupp

(3)计算当前霍夫空间的累计数组S(p)的局部最大值,那么对应的就是原始图像中曲线f(x,p)=0的解析实现

Opencv中的霍夫变换算法并没有直接将曲线提取出去,而是返回相应的(r,\theta)平面的局部最大值,因此需要对Opencv中的函数参数接口进一步理解分析。Opencv中提供了不同种类的霍夫变换函数:标准的霍夫变换(SHT)、多尺度霍夫变换(MHT)及统计概率霍夫变换(PPHT)。标准与多尺度霍夫变换都是用HoughLines()函数来实现的。

void HoughLinesP(InputArray image,OutputArray lines,double rho,double theta,int threshold,double minLineLength=0,double maxLineGap=0);

实现标准霍夫变换线检测。参数image为输入的8位单通道二值化图像;lines为输出线向量,每个线向量有4个元素(x_{1},x_{2},y_{1},y_{2})组成,其中(x_{1},y_{1})(x_{2},y_{2})为线段的终点坐标;rho为累计像素的距离分辨率;theta为累计弧度的角度分辨率;Threshold表示要检测一条直线所需最少的曲线交点;minLineLength为最小的线长度;maxLineGap为最大的长度,用于线段连接。

void HoughLines(InputArray Image,OutputArray lines,double rho,double theta,int threshold,double srn=0,double stn=0);

实现统计概率的霍夫变换线检测。参数image为输入的8位单通道二值化图像;lines为输出线向量,每个线向量由两个元素(p,\theta)组成,其中p为距离原点的距离,\theta为线旋转角;rho为累计像素的距离分辨率;theta为累计弧度的角度分辨率;threshold表示要检测一条直线所需最少的曲线交点;srn为多尺度霍夫变换参数,是一个距离分辨率p因子;stn为多尺度霍夫变换参数,是一个距离分辨率\theta因子。

e.g:

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(void)
{
	Mat srcImage = imread("picture4.jpg");

	if (!srcImage.data)
	{
		return -1;
	}

	imshow("srcImage", srcImage);

	Mat edgeMat, houghMat;
	//Canny边缘检测,二值图像
	Canny(srcImage, edgeMat,50,200,3);

	cvtColor(edgeMat, houghMat,CV_GRAY2BGR);

	#if 0

	//标准的霍夫检测

	vector<Vec2f> lines;
	HoughLines(edgeMat, lines, 1, CV_PI / 180, 100, 0, 0);
	
	for (size_t i = 0; i < lines.size(); i++)
	{
		float rho = lines[i][0], theta = lines[i][0];
		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(houghMat,pt1,pt2,Scalar(0,0,255),3,CV_AA);
	}

    #else

	//统计概率的霍夫变换
	vector<Vec4i> lines;
	HoughLinesP(edgeMat,lines,1,CV_PI/180,50,50,10);
	for (size_t i = 0; i < lines.size(); i++)
	{
		Vec4i l = lines[i];
		line(houghMat, Point(l[0], l[1]), Point(l[2],l[3]),Scalar(0,0,255),3,CV_AA);

	}

	#endif 

	imshow("Hough", houghMat);

	waitKey(0);

	return 0;
}

运行结果如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值