zoukankan      html  css  js  c++  java
  • 霍夫变换理解

    霍夫变换可以用于直线检测,圆检测等。我需要解决的问题是二维点云线特征提取,相关文献上说霍夫变换可以提取,决定深入学习一下。

    先上两张图:直线的表达式采用极坐标表示ρ=xcosθ+ysinθ,关于ρθ的几何意义如图。证明下面的图可以说明。

    因此过某一点A的极坐标方程可以表示所有过A点的直线族。 同理过某一点B的极坐标方程可以表示过有过点B的直线族。两个直线族的集合就是同时过A点和B点的直线。

    霍夫变换首先将极坐标系的纵横坐标轴ρθ离散化,构成一个网格m*n的数组。这样对栅格图像的每一个非0点进行霍夫变换,同时对相应的数组元素进行累加。

    霍夫空间栅格图

    OpenCV中的源码帮助理解一下:

     1 static void icvHoughLinesStandard( const CvMat* img, float rho, float theta,
     2                        int threshold, CvSeq *lines, int linesMax )
     3 {
     4     cv::AutoBuffer<int> _accum, _sort_buf;
     5     cv::AutoBuffer<float> _tabSin, _tabCos;
     6 
     7     const uchar* image;
     8     int step, width, height;
     9     int numangle, numrho;
    10     int total = 0;
    11     int i, j;
    12     float irho = 1 / rho;
    13     double scale;
    14 
    15     CV_Assert( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 );
    16 
    17     image = img->data.ptr;
    18     step = img->step;
    19     width = img->cols;
    20     height = img->rows;
    21 
    22     numangle = cvRound(CV_PI / theta);//对角度进行等分
    23     numrho = cvRound(((width + height) * 2 + 1) / rho);//对半径进行等分?
    24 
    25     _accum.allocate((numangle+2) * (numrho+2));
    26     _sort_buf.allocate(numangle * numrho);
    27     _tabSin.allocate(numangle);
    28     _tabCos.allocate(numangle);
    29     int *accum = _accum, *sort_buf = _sort_buf;
    30     float *tabSin = _tabSin, *tabCos = _tabCos;
    31 
    32     memset( accum, 0, sizeof(accum[0]) * (numangle+2) * (numrho+2) );//定义了一个numangle*numrho数组
    33 
    34     float ang = 0;
    35     for(int n = 0; n < numangle; ang += theta, n++ )
    36     {
    37         tabSin[n] = (float)(sin((double)ang) * irho);
    38         tabCos[n] = (float)(cos((double)ang) * irho);
    39     }
    40 
    41     // stage 1. fill accumulator
    42     for( i = 0; i < height; i++ )
    43         for( j = 0; j < width; j++ )
    44         {
    45             if( image[i * step + j] != 0 )
    46                 for(int n = 0; n < numangle; n++ )
    47                 {
    48                     int r = cvRound( j * tabCos[n] + i * tabSin[n] );
    49                     r += (numrho - 1) / 2;
    50                     accum[(n+1) * (numrho+2) + r+1]++;
    51                 }
    52         }
    53 
    54     // stage 2. find local maximums
    55     for(int r = 0; r < numrho; r++ )
    56         for(int n = 0; n < numangle; n++ )
    57         {
    58             int base = (n+1) * (numrho+2) + r+1;
    59             if( accum[base] > threshold &&
    60                 accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] &&
    61                 accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] )
    62                 sort_buf[total++] = base;
    63         }
    64 
    65     // stage 3. sort the detected lines by accumulator value
    66     icvHoughSortDescent32s( sort_buf, total, accum );//快速排序
    67 
    68     // stage 4. store the first min(total,linesMax) lines to the output buffer
    69     linesMax = MIN(linesMax, total);
    70     scale = 1./(numrho+2);
    71     for( i = 0; i < linesMax; i++ )//从数组中取前linesMax条线
    72     {
    73         CvLinePolar line;
    74         int idx = sort_buf[i];
    75         int n = cvFloor(idx*scale) - 1;
    76         int r = idx - (n+1)*(numrho+2) - 1;
    77         line.rho = (r - (numrho - 1)*0.5f) * rho;
    78         line.angle = n * theta;
    79         cvSeqPush( lines, &line );
    80     }
    81 }

     接下来需要思考如何用于霍夫变换进行二维激光点云的线特征提取。另外一个问题是三维点云的线特征如何提取?

  • 相关阅读:
    如何查看oracle表空间已使用大小
    Oracle 和 SQL Server 数据类型对照表
    【转】Oracle TO_DATE 日期格式
    Eclipse 报 “Exception in thread "main" java.lang.OutOfMemoryError: Java heap space ”错误的解决办法
    【转】利用ftpclient下载文件,解决用window.open打开ftp地址中有中文,不能下载的问题
    JavaScript学习
    SQL Server 2008的一些问题及解决办法
    oracle的一些学习
    【转】更改远程桌面默认端口3389及删除远程桌面连接历史记录
    【转】oracle10g的scott用户无法登陆的解决办法,即ora28000 the account is locked错误代码
  • 原文地址:https://www.cnblogs.com/yhlx125/p/5164739.html
Copyright © 2011-2022 走看看