霍夫变换

      霍夫变换可以用于查找图片中存在的直线或圆,常用于车道线检测、路牌检测等中。其基本理论是二值化图像上的任何点都有可能是一些候选直线集合的一部分。在平面直角坐标系(x-y)中,一条直线可以用下式表示。


     y=kx+b

     对于直线上一个确定的点(x_0,y_0),有:y_0=kx_0+b

     这表示参数平面(k-b)中的一条直线。因此,图像中的一个点对应参数平面中的一条直线,图像中的一条直线对应参数平面中的一个点。对图像上所有的点作霍夫变换,最终所要检测的直线对应的一定是参数平面中直线相交最多的那个点。这样就在图像中检测出了直线。在实际应用中,直线通常采用参数方程:



opencv中集合了两种霍夫变换:标准霍夫变换(SHT)和累计概率霍夫变换(PPHT)。函数如下:

CvSeq *cvHounghLines2 (
CvArr* image,
void* line_storage,  // 保存结果位置的指针
int method,
double rho,
double  theta,
int threshold,
double param1 = 0,
double param2 = 0
);


method 可以是:CV_HOUGH_STANDARD,CV_HOUGH_PROBABILISTIC 或者CV_HOUGH_MULTI_SCALE,分别对应SHT,PPHT或者SHT的多尺度变种。

rho, theta用来设置直线所需的分辨率。rho的单位是像素,theta的单位是弧度。

SHT中没有使用param1、param2参数。对于PPHT,param1设置为将要返回的线段的最小长度,param2设置为一条直线上分离线段不能连成一条直线的分割像素点数。而在多尺度的HT,这两个参数是用来芝麻应呗计算的直线参数中较高的分辨率。

对于SHT,可以使用下列命令得到返回的检测直线:

float * line = (float *) cvGetSeqElem(lines,i);


对于PPHT,则有:

CvPoint * line = (CvPoint *) cvGetSeqElem(lines,i);

下面给出完整的霍夫变换检测直线示例:


#include <stdio.h>
#include <cv.h>
#include "highgui.h"



int main()
{
	cvNamedWindow("grayimg",1);
	cvNamedWindow("edges",1);
	cvNamedWindow("hough",1);
	cvMoveWindow("grayimg",0,0);
	cvMoveWindow("edges",300,60);
	cvMoveWindow("hough",30,120);
	IplImage * img = cvLoadImage("e:/3.jpg");
	IplImage * gray = NULL,*edges = NULL, *houghimg = NULL;
	CvSize size;
	size.width = img->width;
	size.height = img->height;
	CvMemStorage * storage = cvCreateMemStorage(0);

	CvSeq *lines = 0;

	gray = cvCreateImage(size,img->depth,1);
	edges = cvCreateImage(size,img->depth,1);
	houghimg = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
	cvCvtColor(img,gray,CV_RGB2GRAY);
	cvCanny(gray,edges,50,100,3); //先找出二值图像的边缘
	
	cvCopy(img,houghimg);
	
	lines = cvHoughLines2(edges,storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180,10,20,10 );
	//printf("%d\n",lines->total);

	int index; // index 为直线索引
	for (index = 0; index < lines->total; index ++)
	{
		CvPoint *line = (CvPoint *)cvGetSeqElem(lines,index);
		cvLine(houghimg,line[0],line[1],CV_RGB(255,0,0),3,8);
	}


	cvShowImage("grayimg",gray);
	cvShowImage("edges",edges);
	cvShowImage("hough",houghimg);
	cvWaitKey();
	cvDestroyAllWindows();
	cvReleaseImage( &gray );
	cvReleaseImage(&img);
	cvReleaseImage( &edges );
	system("pause");
	return 0;
	
}
实验结果:实验中的参数将会影响检测到的直线数量。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值