Hough Transform 霍夫變換檢測直線

这篇博客详细介绍了霍夫变换检测图像中直线的原理,从理论到代码,阐述了坐标变换、直线条件以及如何通过累加ρ值来找到直线。在实践中,通过对θ角度的划分和ρ的计算,利用二维表格进行累计,找到局部最大值以确定直线的θ和ρ参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.cnblogs.com/smartvessel/archive/2011/10/20/2218654.html

從理論到代碼,再從代碼到理論

(1)理論之通俗理解:

1.在圖像中檢測直線的問題,其實質是找到構成直線的所有的像素點。那麼問題就是從找到直線,變成找到符合y=mx+c的所有(x,y)的點的問題。

2.進行坐標系變化y=mx+c,變成c=-xm+b。直線上的點(x1,y1),在轉換坐標系後為一條直線。這個原理應該是高中的。

  

3.直線上每一個點在MC坐標系中都表現為直線,而且,這些直線都相交於一個點,(m,c)。找到所有點的問題,轉變為尋找直線的問題。

4.對於圖像中的每一個點,在MC坐標系中對應著很多的直線。找到直線的交點,就對應著找到圖像中的直線。

實際在使用這一原理的時候,不是采用直線的斜率和截距公式,而是用

如何實現:

1.       將θ角在-90度到90度的范圍裡,劃分為很多區間,對所有的像素點(x,y)在所有θ角的時候,求出ρ.從而累加ρ值出現的次數。高於某個閾值的ρ就是一個直線。

2.       這個過程就類似於如下一個二維的表格,橫坐標就是θ角,ρ就是到直線的最短距離。

橫坐標θ不斷變換,對於所有的不為0的像素點,計算出ρ,找到ρ在坐標(θ,ρ)的位置累加1.

3.       上圖中局部最大的就是找到的直線的θ和ρ的值。

(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++ )
    {
        CvLinePolar 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;
        cvSeqPush( lines, &line );
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值