本文主要是介绍hough变换拟合直线,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在实际应用中,y=k*x+b形式的直线方程没有办法表示x=c形式的直线(这时候,直线的斜 率为无穷大)。所以实际应用中,是采用参数方程p=x*cos(theta)+y*sin(theta)。这样,图像平面 上的一个点就对应到参数p—theta平面上的一条曲线上。其它的还是一样。Hough变换求取直线的源码:
- //提取直线 能够在二值图像中提取场地中的白线,并进行重建
- //采用Hough变换
- #include <iostream>
- #include<cv.h>
- #include <highgui.h>
- #include <math.h>
- #define PI 3.1415926
- using namespace std;
- int main(){
- IplImage * image,*image2;
- image = cvLoadImage("E:\\image\\game\\board.bmp",0);
- cvNamedWindow("image",1);
- cvShowImage("image",image);
- //Hough变换
- //用Hough提取出所有的直线,并在一张新图中进行绘制
- image2 = cvCreateImage(cvSize(image->width,image->height),image->depth,1);
- int i,j;
- unsigned char *ptr,* dst;
- //参数空间的参数 角度0~度 每格2度 distance = fabs(x*cosA + y *sinA)
- double angle;
- int distance;
- int PerAngle = 2;
- int m,n;
- int AngleNum = 90; //角度范围0~360度
- int maxDistance = (int)(sqrt(pow((double)image->width,2)+ pow((double)image->height,2)) + 2 );
- //cout<<maxDistance<<endl;
- //参数空间各个点的统计值,使用一维数组,排序方便
- //申请一块内存,存放各个直线的出现次数
- int * number = new int [AngleNum * maxDistance];
- double Hsin,Hcot;
- int count = 0;
- int max ,lineAngle, rol;
- //number赋值0
- for (i= 0; i< AngleNum * maxDistance; i++)
- {
- number[i] = 0;
- }
- for (i = 0 ; i< image->height; i++)
- {
- for (j = 0 ; j < image->width ; j++)
- {
- ptr = (unsigned char *)image->imageData + i*image->widthStep +j;
- //统计每个直线出现的概率
- if ( *ptr != 0)
- {
- //count++;
- //cout<<count<<endl;
- for (m = 0 ; m < AngleNum; m++ )
- {
- angle = (double)m*PerAngle*PI/180.0;
- distance = (int)(fabs(j*cos(angle)+ i*sin(angle)));
- //cout<<"distance: "<< distance<<endl;
- //*(number+ AngleNum* (int)(distance + 0.5) + m) = (*(number+ AngleNum* (int)(distance + 0.5) + m)) +1;
- number[AngleNum * distance + m]++;
- }
- }
- }
- }
- //打印各个方格的统计个数
- for (m = 0 ; m <maxDistance; m++)
- {
- for (n = 0 ; n < AngleNum; n++ )
- {
- if (number[AngleNum * m + n] > 100)
- {
- printf("angle %d distance : %d number %d\n",n*2 , m , number[AngleNum* m + n] );
- }
- }
- }
- //首先将image2 的所有值赋值为0
- for (i = 0 ; i< image2->height; i++)
- {
- for (j = 0 ; j< image2->width; j++)
- {
- dst =(unsigned char *) image2->imageData + i*image->widthStep + j;
- *dst =0;
- }
- }
- //寻找变换域中的直线 假设一条直线上有20个点以上,则认为是一条直线 那么就在新的图片中画出该直线
- //寻找概率最大的直线
- /* 添加直线
- lineAngle = 0;
- rol = 0;
- max = number[0];
- for (m = 0 ;m< maxDistance ;m++ )
- {
- for (n = 0 ; n< AngleNum; n++)
- {
- if (number[AngleNum * m + n] > max)
- {
- max =number[AngleNum * m + n];
- rol = m;
- lineAngle = n;
- }
- }
- }
- cout<<"m :" <<rol<<" n:"<<lineAngle<<" max" << max<<endl;
- //根据角度和距离在image2中添加该图片
- angle = lineAngle*PerAngle*PI/180;
- Hcot = cos(angle)/sin(angle);
- Hsin = sin(angle);
- for (j = 0;j< image2->width;j++ )
- {
- i = (int)(rol/Hsin - j*Hcot);
- dst = (unsigned char*)image2->imageData + i*image->widthStep + j;
- *dst = 255;
- }
- //添加第二条直线
- //最大值邻域处赋值为0
- number[rol*AngleNum+ lineAngle] = 0;
- for (m = rol-1 ; m<= rol+1; m++)
- {
- for (n = lineAngle -1 ; n<= lineAngle +1 ; n++)
- {
- number[m*AngleNum + n] = 0;
- }
- }
- max = number[0];
- lineAngle = 0;
- rol = 0;
- for (m = 0 ;m < maxDistance ;m++ )
- {
- for (n = 0 ; n < AngleNum; n++)
- {
- if (number[AngleNum * m + n] > max)
- {
- max =number[AngleNum * m + n];
- rol = m;
- lineAngle = n;
- }
- }
- }
- cout<<"m :" <<rol<<" n:"<<lineAngle<<" max" << max<<endl;
- //根据角度和距离在image2中添加该图片
- angle = lineAngle*PerAngle*PI/180;
- Hcot = cos(angle)/sin(angle);
- Hsin = sin(angle);
- for (j = 0;j< image2->width;j++ )
- {
- i = (int)(rol/Hsin - j*Hcot);
- if (i< 0 ){i = 0;}
- if(i>= image2->height){i = image2->height -1;}
- dst = (unsigned char*)image2->imageData + i*image->widthStep + j;
- *dst = 255;
- }
- */
- //画出所有可能的直线
- for (m = 0 ;m< maxDistance ; m++)
- {
- for (n = 0 ; n< AngleNum ;n++)
- {
- if (number[m*AngleNum + n] > 110)
- {
- rol = m;
- lineAngle = n;
- //根据角度和距离在image2中添加该图片
- angle = lineAngle*PerAngle*PI/180;
- Hcot = cos(angle)/sin(angle);
- Hsin = sin(angle);
- for (j = 0;j< image2->width;j++ )
- {
- i = (int)(rol/Hsin - j*Hcot);
- if (i< 0 ){i = 0;}
- if(i>= image2->height){i = image2->height -1;}
- dst = (unsigned char*)image2->imageData + i*image->widthStep + j;
- *dst = 255;
- }
- }
- }
- }
- cvNamedWindow("image2",1);
- cvShowImage("image2",image2);
- //cvSaveImage("E:\\image\\game\\changjian.bmp",image2);
- delete [] number;
- cvWaitKey(0);
- return 0;
- }
这篇关于hough变换拟合直线的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!