hough变换拟合直线

2023-12-21 11:08
文章标签 直线 拟合 变换 hough

本文主要是介绍hough变换拟合直线,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       在实际应用中,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 plain copy
  1.   
[cpp]  view plain copy
  1.   





这篇关于hough变换拟合直线的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/519754

相关文章

POJ1269 判断2条直线的位置关系

题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,再判断 直线 是否平行, 如果还不是, 则两直线相交。  判断共线:  p1p2q1 共线 且 p1p2q2 共线 ,共线用叉乘为 0  来判断,  判断 平行:  p1p

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

求空间直线与平面的交点

若直线不与平面平行,将存在交点。如下图所示,已知直线L过点m(m1,m2,m3),且方向向量为VL(v1,v2,v3),平面P过点n(n1,n2,n3),且法线方向向量为VP(vp1,vp2,vp3),求得直线与平面的交点O的坐标(x,y,z): 将直线方程写成参数方程形式,即有: x = m1+ v1 * t y = m2+ v2 * t

n条直线最多能划分出多少个平面?

N条直线,两两相交,其交点各不不同,则产生的交点数目为N个数中取2个数的组合; 同时,也只有这种情况下(两两相交,也交点不同),分割的平面数最多, 数目为: 2 + (N-1)(N+2)/2.  这里求最少平面数没有意义,因为最少平面数就是N+1, 即N条直线两两平行的时候,分割的平面最少。 举例: 1条直线分割平面数最多为2; a1 = 2 2条直线分割平面数最多为4;

6. 深度学习中的正则化技术:防止过拟合

引言 过拟合是深度学习模型在训练过程中常遇到的挑战。过拟合会导致模型在训练数据上表现良好,但在新数据上表现不佳。为了防止过拟合,研究者们提出了多种正则化技术,如L1/L2正则化、Dropout、数据增强等。这些技术通过约束模型的复杂度或增加数据的多样性,有效提高了模型的泛化能力。本篇博文将深入探讨这些正则化技术的原理、应用及其在实际深度学习任务中的效果。 1. 过拟合的原因与影响 过拟合通常

【数字信号处理】一文讲清FFT(快速傅里叶变换)

目录 快速傅里叶变换(Fast Fourier Transform,FFT)FFT的背景快速傅里叶变换(Fast Fourier Transform,FFT)DFT的数学表达实际计算重要性和应用频谱泄露、频谱混叠奈奎斯特采样定理参考链接 快速傅里叶变换(Fast Fourier Transform,FFT) FFT的背景 1、为什么要时域→频域频率?50Hz+频率120Hz

傅里叶变换家族

禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》 禹晶、肖创柏、廖庆敏《数字图像处理》资源二维码

齐次变换矩阵的原理与应用

齐次变换矩阵的原理与应用 通过齐次变换矩阵,可以描述机械臂末端执行器(法兰)在三维空间中的平移和旋转操作。该矩阵结合了旋转和平移信息,用于坐标变换。 1. 齐次变换矩阵的基本形式 一个齐次变换矩阵 T是一个 4x4 矩阵,表示刚体的旋转和平移: T = [ R t 0 1 ] = [ r 11 r 12 r 13 x r 21 r 22 r 23 y r 31 r 32 r 33 z 0

MATLAB分析图像的离散余弦变换(DCT)

1. MATLAB的介绍以及所需函数的说明:  1.1 MATLAB  MATLAB是matrix&laboratory两个词的组合,意为矩阵工厂(矩阵实验室)。是由美国mathworks 公司发布的主要面对科学计算、可视化以及交互式程序设计的高科技计算环境。它将数值分析、矩阵计算、科学数据可视化以及非线性动态系统的建模和仿真等诸多强大功能集成在一个易于使用的视窗环境中,为科学研究、工程设