霍夫变换返回共线和半共线点

时间:2013-05-01 19:40:01

标签: c++ opencv hough-transform

我在图像中有分数。我需要检测最共线的点。最快的方法是使用Hough变换,但我必须修改opencv方法。实际上我需要用检测到的线返回半共线点,因此我修改了极线结构。如图所示,还需要公差阈值来检测几乎检测到的点。有人可以帮助如何调整此阈值? 我需要至少四个半共线点来检测它们所属的线。 ex 1 ex 2 ex 3

  1. 第一张图像的点由6条重叠线检测

  2. 中间图像的点没有被检测到

  3. 第三点 通过三行检测
  4. `![enter image description here enter image description here enter image description here

    摆脱重叠留置权的最佳方法是什么?或者如何调整公差阈值以仅通过一条线检测半共线点?

    是我自己的函数调用:

    vector<CvLinePolar2> lines;
    CvMat c_image = source1; // loaded image
    HoughLinesStandard(&c_image,1,CV_PI/180,4,&lines,INT_MAX);
    

        typedef struct CvLinePolar2
        {
          float rho;
          float angle;
          vector<CvPoint> points;
        };
    
    void HoughLinesStandard( const CvMat* img, float rho, float theta,
                       int threshold, vector<CvLinePolar2> *lines, int linesMax= INT_MAX )
    {
    cv::AutoBuffer<int> _accum, _sort_buf;
    cv::AutoBuffer<float> _tabSin, _tabCos;
    
    
    const uchar* image;
    int step, width, height;
    int numangle, numrho;
    int total = 0;
    int i, j;
    float irho = 1 / rho;
    double scale;
    
    vector<vector<CvPoint>> lpoints;
    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) );
    //memset( lpoints, 0, sizeof(lpoints) );
    lpoints.resize(sizeof(accum[0]) * (numangle+2) * (numrho+2));
    float ang = 0;
    for(int n = 0; n < numangle; 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 )
            {
                CvPoint pt;
                pt.x = j; pt.y = i;
                for(int n = 0; n < numangle; n++ )
                {
                    int r = cvRound( j * tabCos[n] + i * tabSin[n] );
                    r += (numrho - 1) / 2;
    
                    int ind = (n+1) * (numrho+2) + r+1;
                    int s = accum[ind];
                    accum[ind]++;
    
                    lpoints[ind].push_back(pt);
    
    
                }
    
            }
        }
    
    // stage 2. find local maximums
    for(int r = 0; r < numrho; r++ )
        for(int n = 0; n < numangle; n++ )
        {
            int base = (n+1) * (numrho+2) + r+1;
            if( accum[base] > threshold &&
                accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] &&
                accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] )
                sort_buf[total++] = base;
        }
    
    // stage 3. sort the detected lines by accumulator value
    icvHoughSortDescent32s( sort_buf, total, accum );
    
    // stage 4. store the first min(total,linesMax) lines to the output buffer
    linesMax = MIN(linesMax, total);
    scale = 1./(numrho+2);
    for( i = 0; i < linesMax; i++ )
    {
        CvLinePolar2 line;
        int idx = sort_buf[i];
        int n = cvFloor(idx*scale) - 1;
        int r = idx - (n+1)*(numrho+2) - 1;
        line.rho = (r - (numrho - 1)*0.5f) * rho;
        line.angle = n * theta;
    
        line.points = lpoints[idx];
    
        lines->push_back(line);
    }
    

    }

2 个答案:

答案 0 :(得分:0)

一种方法是non-maximal suppression来稀疏潜在线的候选集。一旦确定了稀疏的潜在线,您就可以计算出满足某个角度或空间差异阈值的剩余线的平均值。

答案 1 :(得分:0)

试试HoughLinesP .. opencv reference