Hough变换以及C实现

    霍夫变换于1962年由PaulHough 首次提出,后于1972年由RichardDuda和PeterHart推广使用,经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆。

一 基本思想

    Hough的基本思想就是构造参数平面,找出参数平面上的峰值点,从而得到所需检测形状的参数。

    以直线问题来阐述:在找出边界点集之后,需要连接,形成完整的边界图形描述,对于包含n个点的点集,找出共线的点集和直线方程。

构造ab参数平面:


     则xy平面上的任意一条直线y=a*x+b,都对应于参数平面上的一个点,而在xy平面上过一个点的所有直线,构成参数ab平面上的一条直线。

    如果点(x1,y1)与点(x2,y2)共线,那么这两点在参数ab平面上的直线将有一个交点。

 Hough变换以及C实现_第1张图片

    在参数ab平面上相交直线最多的点,对应的xy平面上的直线就是我们的解。

极坐标表示:

    由于垂直直线的斜率为无限大,实际应用常用极坐标来表示,原理和上述一样。

    Hough变换以及C实现_第2张图片

    则上述描述变为:

    (1)在图像空间(x,y)域中的一点对应于参数空间(ρ,θ)域中的一条正弦曲线

    (2)参数空间中的一点对应于图像空间(x,y)中的一条直线。

    (3)图像空间(x,y)域中的一条直线上的n个点,对应于参数空间中经过一个公共点的n条曲线

    (4)变换空间中一条曲线上的n个点对应于空间(x,y)中过一公共点的n条直线。

二 编程方法

(1)建立一个2-D累加数组(可用一维数组表示),设这个累加数组为A(Theta, R)。

(2)开始时设置数组A为0,然后对每个图像空间中的给定边缘点,让Theta取遍Theta轴上所有的可能值,并根据R=x*cos(theta)+y*sin(theta)算出对应的R。

(3)再根据Theta和R的值(都已整数化),对A进行累加:A(Theta , R)++。累加结束后,根据(Theta , R)的值就可知道有多少点是共线的,即A(Theta , R)的值就是在(Theta , R)处共线点的个数,同时(Theta , R)值也给出了直线方程的参数。

三 代码

bool HoughTrans(int* pPoints,int pointNum,int RMax,int &lineR,int &lineTheta)
{
	//x*cos(theta)+y*sin(theta)=r;
	int k,maxValue;
	int *pAccumulateArr=NULL;		//累加数组
	int thetaMax=360;
	int theta;
	int rValue;
	float fRate = (float)(PI/180);
	int AccuArrLength=(thetaMax+1)*(RMax+1);
	
	pAccumulateArr=(int*)malloc(AccuArrLength*sizeof(int));
	memset(pAccumulateArr,0,AccuArrLength*sizeof(int));
	for (k=0;k=0)
			{
				int indexTemp=rValue*(thetaMax+1)+theta;
				if (rValue<=RMax && indexTemp>=0)
				{
					pAccumulateArr[indexTemp]++;
				}
			}
		}
	}
	
	//得到最佳参数
	maxValue=0;
	lineR=0;
	lineTheta=0;
	for (rValue=0;rValue<=RMax;rValue++)
	{
		for (theta=0;theta<=thetaMax;theta++)
		{
			int iCount = pAccumulateArr[rValue * (thetaMax+1) + theta];
			if (maxValue



你可能感兴趣的:(Hough变换以及C实现)