hough变换拟合直线

来源:互联网 发布:淘宝复核认证本人不在 编辑:程序博客网 时间:2024/05/18 00:52

       在实际应用中,y=k*x+b形式的直线方程没有办法表示x=c形式的直线(这时候,直线的斜 率为无穷大)。所以实际应用中,是采用参数方程p=x*cos(theta)+y*sin(theta)。这样,图像平面 上的一个点就对应到参数p—theta平面上的一条曲线上。其它的还是一样。Hough变换求取直线的源码:


  1. //提取直线   能够在二值图像中提取场地中的白线,并进行重建   
  2. //采用Hough变换  
  3.   
  4.   
  5. #include <iostream>  
  6. #include<cv.h>  
  7. #include <highgui.h>  
  8. #include <math.h>  
  9. #define PI 3.1415926  
  10. using namespace std;  
  11.   
  12.   
  13. int main(){  
  14.     IplImage * image,*image2;  
  15.     image = cvLoadImage("E:\\image\\game\\board.bmp",0);  
  16.     cvNamedWindow("image",1);  
  17.     cvShowImage("image",image);  
  18.   
  19.   
  20.   
  21.   
  22.     //Hough变换   
  23.     //用Hough提取出所有的直线,并在一张新图中进行绘制  
  24.     image2  = cvCreateImage(cvSize(image->width,image->height),image->depth,1);  
  25.     int i,j;  
  26.     unsigned char *ptr,* dst;  
  27.     //参数空间的参数 角度0~度 每格2度 distance = fabs(x*cosA + y *sinA)  
  28.     double angle;  
  29.     int distance;  
  30.     int PerAngle = 2;   
  31.     int m,n;  
  32.     int AngleNum = 90; //角度范围0~360度  
  33.     int maxDistance = (int)(sqrt(pow((double)image->width,2)+ pow((double)image->height,2)) + 2 );  
  34.     //cout<<maxDistance<<endl;  
  35.     //参数空间各个点的统计值,使用一维数组,排序方便  
  36.     //申请一块内存,存放各个直线的出现次数  
  37.       
  38.     int * number = new int [AngleNum * maxDistance];  
  39.     double Hsin,Hcot;  
  40.     int count = 0;  
  41.     int max ,lineAngle, rol;  
  42.       
  43.     //number赋值0  
  44.     for (i= 0; i< AngleNum * maxDistance; i++)  
  45.     {  
  46.         number[i] = 0;  
  47.     }  
  48.       
  49.       
  50.     for (i = 0 ; i< image->height; i++)  
  51.     {  
  52.         for (j = 0 ; j < image->width ; j++)  
  53.         {  
  54.             ptr = (unsigned char *)image->imageData + i*image->widthStep +j;  
  55.             //统计每个直线出现的概率  
  56.               
  57.                 if ( *ptr != 0)  
  58.                 {  
  59.                     //count++;  
  60.                     //cout<<count<<endl;  
  61.                     for (m = 0 ; m < AngleNum; m++ )  
  62.                     {  
  63.                         angle = (double)m*PerAngle*PI/180.0;  
  64.                         distance = (int)(fabs(j*cos(angle)+ i*sin(angle)));  
  65.                         //cout<<"distance:    "<< distance<<endl;   
  66.                         //*(number+ AngleNum* (int)(distance + 0.5) + m) = (*(number+ AngleNum* (int)(distance + 0.5) + m)) +1;  
  67.                         number[AngleNum * distance + m]++;  
  68.                     }  
  69.                       
  70.                 }  
  71.         }  
  72.   
  73.   
  74.     }  
  75.     //打印各个方格的统计个数  
  76.     for (m = 0 ; m <maxDistance; m++)  
  77.     {  
  78.         for (n = 0 ; n < AngleNum;  n++ )  
  79.         {  
  80.             if (number[AngleNum * m + n] > 100)  
  81.             {  
  82.                     printf("angle %d   distance : %d   number %d\n",n*2 , m , number[AngleNum* m + n] );  
  83.             }  
  84.       
  85.         }  
  86.     }  
  87.   
  88.   
  89.   
  90.   
  91.       
  92.     //首先将image2 的所有值赋值为0  
  93.   
  94.   
  95.     for (i = 0 ; i< image2->height; i++)  
  96.     {  
  97.         for (j = 0 ; j< image2->width; j++)  
  98.         {  
  99.             dst =(unsigned char *) image2->imageData + i*image->widthStep + j;  
  100.             *dst =0;  
  101.         }  
  102.     }  
  103.   
  104.   
  105.     //寻找变换域中的直线 假设一条直线上有20个点以上,则认为是一条直线 那么就在新的图片中画出该直线  
  106.     //寻找概率最大的直线   
  107.       
  108.     /* 添加直线  
  109.     lineAngle = 0;  
  110.      rol = 0;  
  111.      max = number[0];  
  112.     for (m = 0 ;m<  maxDistance ;m++ )  
  113.     {  
  114.         for (n = 0 ; n< AngleNum; n++)  
  115.         {  
  116.             if (number[AngleNum * m + n] > max)  
  117.             {  
  118.                 max =number[AngleNum * m + n];  
  119.                 rol = m;  
  120.                 lineAngle = n;  
  121.             }  
  122.   
  123.   
  124.         }  
  125.     }  
  126.     cout<<"m :" <<rol<<"   n:"<<lineAngle<<"    max" << max<<endl;  
  127.   
  128.   
  129.     //根据角度和距离在image2中添加该图片  
  130.     angle = lineAngle*PerAngle*PI/180;  
  131.     Hcot = cos(angle)/sin(angle);  
  132.     Hsin = sin(angle);  
  133.     for (j = 0;j< image2->width;j++ )  
  134.     {  
  135.           
  136.         i = (int)(rol/Hsin - j*Hcot);  
  137.         dst = (unsigned char*)image2->imageData + i*image->widthStep + j;  
  138.         *dst = 255;  
  139.     }  
  140.   
  141.   
  142.   
  143.   
  144.     //添加第二条直线  
  145.     //最大值邻域处赋值为0  
  146.     number[rol*AngleNum+ lineAngle] = 0;  
  147.     for (m = rol-1 ; m<= rol+1; m++)  
  148.     {  
  149.         for (n = lineAngle -1 ; n<= lineAngle +1 ; n++)  
  150.         {  
  151.             number[m*AngleNum + n] = 0;  
  152.         }  
  153.     }  
  154.       
  155.     max = number[0];  
  156.     lineAngle = 0;  
  157.     rol = 0;  
  158.   
  159.   
  160.     for (m = 0 ;m <  maxDistance ;m++ )  
  161.     {  
  162.         for (n = 0 ; n < AngleNum; n++)  
  163.         {  
  164.             if (number[AngleNum * m + n] > max)  
  165.             {  
  166.                 max =number[AngleNum * m + n];  
  167.                 rol = m;  
  168.                 lineAngle = n;  
  169.             }  
  170.   
  171.   
  172.         }  
  173.     }  
  174.     cout<<"m :" <<rol<<"   n:"<<lineAngle<<"    max" << max<<endl;  
  175.   
  176.   
  177.     //根据角度和距离在image2中添加该图片  
  178.     angle = lineAngle*PerAngle*PI/180;  
  179.     Hcot = cos(angle)/sin(angle);  
  180.     Hsin = sin(angle);  
  181.     for (j = 0;j< image2->width;j++ )  
  182.     {  
  183.           
  184.         i = (int)(rol/Hsin - j*Hcot);  
  185.         if (i< 0 ){i = 0;}  
  186.         if(i>= image2->height){i = image2->height -1;}  
  187.         dst = (unsigned char*)image2->imageData + i*image->widthStep + j;  
  188.         *dst = 255;  
  189.     }  
  190.   
  191.   
  192.     */  
  193.   
  194.   
  195.   
  196.   
  197.     //画出所有可能的直线  
  198.      for (m = 0 ;m< maxDistance ; m++)  
  199.      {  
  200.          for (n = 0 ; n< AngleNum ;n++)  
  201.          {  
  202.              if (number[m*AngleNum + n] > 110)  
  203.              {  
  204.                  rol = m;  
  205.                  lineAngle = n;  
  206.   
  207.   
  208.                  //根据角度和距离在image2中添加该图片  
  209.                  angle = lineAngle*PerAngle*PI/180;  
  210.                  Hcot = cos(angle)/sin(angle);  
  211.                  Hsin = sin(angle);  
  212.                  for (j = 0;j< image2->width;j++ )  
  213.                  {  
  214.   
  215.   
  216.                      i = (int)(rol/Hsin - j*Hcot);  
  217.                      if (i< 0 ){i = 0;}  
  218.                      if(i>= image2->height){i = image2->height -1;}  
  219.                      dst = (unsigned char*)image2->imageData + i*image->widthStep + j;  
  220.                      *dst = 255;  
  221.                  }  
  222.              }  
  223.               
  224.   
  225.   
  226.          }  
  227.      }  
  228.   
  229.   
  230.     cvNamedWindow("image2",1);  
  231.     cvShowImage("image2",image2);  
  232.     //cvSaveImage("E:\\image\\game\\changjian.bmp",image2);  
  233.       
  234.     delete [] number;  
  235.     cvWaitKey(0);  
  236.     return 0;  
  237. }  


[cpp] view plaincopy
  1.   
[cpp] view plaincopy
  1.   





0 0
原创粉丝点击