本文介绍了OpenCV:获取霍夫累加器值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以从霍夫变换中获得累加器值以及rhotheta?

Is it possible to get the accumulator value along with rho and theta from a Hough transform?

我问是因为我想区分定义明确"(即,累加器值高)的行和定义不明确的行.

I ask because I'd like to differentiate between lines which are "well defined" (ie, which have a high accumulator value) and lines which aren't as well defined.

谢谢!

推荐答案

好,所以看cvhough.cpp文件,结构CvLinePolar仅由rho和angle定义.

Ok, so looking at the cvhough.cpp file, the structure CvLinePolar is only defined by rho and angle.

这是我们对HoughLines的调用所传递的所有信息.我正在修改c ++文件,看看是否可以投票.

This is all that is passed back as a result of our call to HoughLines. I am in the process of modifying the c++ file and see if i can get the votes out.

更新10月26日:刚刚意识到这些并不是真正的答案,而更像是问题.显然皱了皱眉.我找到了一些有关重新编译OpenCV的说明.我猜我们将不得不进入代码并对其进行修改并重新编译.如何在Win32上安装OpenCV 2.0

Update oct 26: just realized these are not really answers but more like questions. apparently frowned upon. I found some instructions on recompiling OpenCV. I guess we'll have to go in the code and modify it and recompile.How to install OpenCV 2.0 on win32

10月27日更新:好吧,我无法使用新代码为OpenCV编译dll,因此我最终将要修改的特定部分复制粘贴到自己的文件中.我喜欢添加新功能,以避免过载已定义的功能.您需要复制以下4个主要内容:1-一些随机定义

update Oct 27: well, i failed at compiling the dlls for OpenCV with my new code so I ended up copy-pasting the specific parts I want to modify into my own files.I like to add new functions so to avoid overloading the already defined functions.There are 4 main things you need to copy over:1- some random defines

#define hough_cmp_gt(l1,l2) (aux[l1] > aux[l2])
static CV_IMPLEMENT_QSORT_EX( icvHoughSortDescent32s, int, hough_cmp_gt, const int* )

2-重新定义线参数的结构

2- redefining the struct for line parameters

typedef struct CvLinePolar2
{
    float rho;
    float angle;
    float votes;
}
CvLinePolar2;

3-被修改的主要功能

3- the main function that was modified

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) );

    for( ang = 0, 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 )
                for( n = 0; n < numangle; n++ )
                {
                    r = cvRound( j * tabCos[n] + i * tabSin[n] );
                    r += (numrho - 1) / 2;
                    accum[(n+1) * (numrho+2) + r+1]++;
                }
        }

    // stage 2. find local maximums
    for( r = 0; r < numrho; r++ )
        for( 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.votes = accum[idx];
        cvSeqPush( lines, &line );
    }

    cvFree( (void**)&sort_buf );
    cvFree( (void**)&accum );
    cvFree( (void**)&tabSin );
    cvFree( (void**)&tabCos);

}

4-调用该函数的函数

4- the function that calls that function

CV_IMPL CvSeq*
cvHoughLines3( CvArr* src_image, void* lineStorage, int method,
               double rho, double theta, int threshold,
               double param1, double param2 )
{
    CvSeq* result = 0;

    CvMat stub, *img = (CvMat*)src_image;
    CvMat* mat = 0;
    CvSeq* lines = 0;
    CvSeq lines_header;
    CvSeqBlock lines_block;
    int lineType, elemSize;
    int linesMax = INT_MAX;
    int iparam1, iparam2;

    img = cvGetMat( img, &stub );

    if( !CV_IS_MASK_ARR(img))
        CV_Error( CV_StsBadArg, "The source image must be 8-bit, single-channel" );

    if( !lineStorage )
        CV_Error( CV_StsNullPtr, "NULL destination" );

    if( rho <= 0 || theta <= 0 || threshold <= 0 )
        CV_Error( CV_StsOutOfRange, "rho, theta and threshold must be positive" );

    if( method != CV_HOUGH_PROBABILISTIC )
    {
        lineType = CV_32FC3;
        elemSize = sizeof(float)*3;
    }
    else
    {
        lineType = CV_32SC4;
        elemSize = sizeof(int)*4;
    }

    if( CV_IS_STORAGE( lineStorage ))
    {
        lines = cvCreateSeq( lineType, sizeof(CvSeq), elemSize, (CvMemStorage*)lineStorage );
    }
    else if( CV_IS_MAT( lineStorage ))
    {
        mat = (CvMat*)lineStorage;

        if( !CV_IS_MAT_CONT( mat->type ) || (mat->rows != 1 && mat->cols != 1) )
            CV_Error( CV_StsBadArg,
            "The destination matrix should be continuous and have a single row or a single column" );

        if( CV_MAT_TYPE( mat->type ) != lineType )
            CV_Error( CV_StsBadArg,
            "The destination matrix data type is inappropriate, see the manual" );

        lines = cvMakeSeqHeaderForArray( lineType, sizeof(CvSeq), elemSize, mat->data.ptr,
                                         mat->rows + mat->cols - 1, &lines_header, &lines_block );
        linesMax = lines->total;
        cvClearSeq( lines );
    }
    else
        CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" );

    iparam1 = cvRound(param1);
    iparam2 = cvRound(param2);

    switch( method )
    {
    case CV_HOUGH_STANDARD:
          icvHoughLinesStandard2( img, (float)rho,
                (float)theta, threshold, lines, linesMax );
          break;

    default:
        CV_Error( CV_StsBadArg, "Unrecognized method id" );
    }

    if( mat )
    {
        if( mat->cols > mat->rows )
            mat->cols = lines->total;
        else
            mat->rows = lines->total;
    }
    else
        result = lines;

    return result;
}

我想您可以卸载opencv,以便它取消所有这些自动路径设置,并使用CMake方法自己重新编译,然后使用OpenCV即可.

And i guess you could uninstall opencv so it takes off all those automatic path setting and recompile it yourself using the CMake method and then the OpenCV is really whatever you make it.

这篇关于OpenCV:获取霍夫累加器值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 19:27