【问题标题】:Search for lines with a small range of angles in OpenCV在 OpenCV 中搜索具有小角度范围的线
【发布时间】:2010-08-09 22:20:40
【问题描述】:

我在 OpenCV 中使用霍夫变换来检测线条。但是,我事先知道我只需要在非常有限的角度范围内(大约 10 度左右)内的线条。我是在对性能非常敏感的环境中执行此操作的,因此我想避免在检测其他角度的线条上花费额外的工作,这些线条我事先知道我不关心。

我可以从 OpenCV 中提取 Hough 源代码,然后将其破解以获取 min_rho 和 max_rho 参数,但我想要一种不那么脆弱的方法(必须手动更新我的代码 w/每次 OpenCV 更新等)。

这里最好的方法是什么?

【问题讨论】:

    标签: opencv hough-transform


    【解决方案1】:

    好吧,我已经修改了icvHoughlines 函数以适用于特定范围的角度。我确信也有更简洁的方式来处理内存分配,但是对于从 180 度到 60 度的角度范围,我的速度提升从 100 毫秒到 33 毫秒,所以我对此很满意。

    注意此代码还输出累加器值。另外,我只输出 1 行,因为这符合我的目的,但那里并没​​有真正的收获。

    static void
    icvHoughLinesStandard2( const CvMat* img, float rho, float theta,
                           int threshold, CvSeq *lines, int linesMax )
    {
        cv::AutoBuffer<int> _accum, _sort_buf;
        cv::AutoBuffer<float> _tabSin, _tabCos;
    
        const uchar* image;
        int step, width, height;
        int numangle, numrho;
        int total = 0;
        float ang;
        int r, n;
        int i, j;
        float irho = 1 / rho;
        double scale;
    
        CV_Assert( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 );
    
        image = img->data.ptr;
        step = img->step;
        width = img->cols;
        height = img->rows;
    
        numangle = cvRound(CV_PI / theta);
        numrho = cvRound(((width + height) * 2 + 1) / rho);
    
        _accum.allocate((numangle+2) * (numrho+2));
        _sort_buf.allocate(numangle * numrho);
        _tabSin.allocate(numangle);
        _tabCos.allocate(numangle);
        int *accum = _accum, *sort_buf = _sort_buf;
        float *tabSin = _tabSin, *tabCos = _tabCos;
    
        memset( accum, 0, sizeof(accum[0]) * (numangle+2) * (numrho+2) );
    
        // find n and ang limits (in our case we want 60 to 120
        float limit_min = 60.0/180.0*PI;
        float limit_max = 120.0/180.0*PI;
    
        //num_steps = (limit_max - limit_min)/theta;
        int start_n = floor(limit_min/theta);
        int stop_n = floor(limit_max/theta);
    
        for( ang = limit_min, n = start_n; n < stop_n; ang += theta, n++ )
        {
            tabSin[n] = (float)(sin(ang) * irho);
            tabCos[n] = (float)(cos(ang) * irho);
        }
    
    
    
        // stage 1. fill accumulator
        for( i = 0; i < height; i++ )
            for( j = 0; j < width; j++ )
            {
                if( image[i * step + j] != 0 )
                            //
            for( n = start_n; n < stop_n; n++ )
                    {
                        r = cvRound( j * tabCos[n] + i * tabSin[n] );
                        r += (numrho - 1) / 2;
                        accum[(n+1) * (numrho+2) + r+1]++;
                    }
            }
    
    
    
        int max_accum = 0;
        int max_ind = 0;
    
        for( r = 0; r < numrho; r++ )
        {
            for( n = start_n; n < stop_n; n++ )
            {
                int base = (n+1) * (numrho+2) + r+1;
                if (accum[base] > max_accum)
                {
                    max_accum = accum[base];
                    max_ind = base;
                }
            }
        }   
    
        CvLinePolar2 line;
        scale = 1./(numrho+2);
        int idx = max_ind;
        n = cvFloor(idx*scale) - 1;
        r = idx - (n+1)*(numrho+2) - 1;
        line.rho = (r - (numrho - 1)*0.5f) * rho;
        line.angle = n * theta;
        line.votes = accum[idx];
        cvSeqPush( lines, &line );
    
    }
    

    【讨论】:

      【解决方案2】:

      如果您使用概率霍夫变换,则输出为 cvPoint 的形式,每个参数用于 lines[0] 和 lines[1] 参数。我们可以通过 pt1.x、pt1.y 和 pt2.x 和 pt2.y 得到两个点的 x 和 y 坐标。 然后使用简单的公式求直线的斜率 - (y2-y1)/(x2-x1)。取其 arctan(tan 倒数)将产生以弧度为单位的角度。然后简单地从获得的每条霍夫线的值中过滤掉所需的角度。

      【讨论】:

        【解决方案3】:

        我认为使用标准 HoughLines(...) 函数更自然,它直接在 rho 和 theta 项中提供线的集合并从中选择必要的角度范围,而不是从线段端点重新计算角度。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-31
          • 2022-09-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多