close

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) 具體代碼片段

[cpp] view plain copy
  1. for( ang = 0, n = 0; n < numangle; ang += theta, n++ )  
  2.     {  
  3.         tabSin[n] = (float)(sin(ang) * irho);  
  4.         tabCos[n] = (float)(cos(ang) * irho);  
  5.     }  
  6.   
  7.     // stage 1. fill accumulator  
  8.     for( i = 0; i < height; i++ )  
  9.         for( j = 0; j < width; j++ )  
  10.         {  
  11.             if( image[i * step + j] != 0 )  
  12.                 for( n = 0; n < numangle; n++ )  
  13.                 {  
  14.                     r = cvRound( j * tabCos[n] + i * tabSin[n] );  
  15.                     r += (numrho - 1) / 2;  
  16.                     accum[(n+1) * (numrho+2) + r+1]++;  
  17.                 }  
  18.         }  
  19.   
  20.     // stage 2. find local maximums  
  21.     for( r = 0; r < numrho; r++ )  
  22.         for( n = 0; n < numangle; n++ )  
  23.         {  
  24.             int base = (n+1) * (numrho+2) + r+1;  
  25.             if( accum[base] > threshold &&  
  26.                 accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] &&  
  27.                 accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] )  
  28.                 sort_buf[total++] = base;  
  29.         }  
  30.   
  31.     // stage 3. sort the detected lines by accumulator value  
  32.     icvHoughSortDescent32s( sort_buf, total, accum );  
  33.   
  34.     // stage 4. store the first min(total,linesMax) lines to the output buffer  
  35.     linesMax = MIN(linesMax, total);  
  36.     scale = 1./(numrho+2);  
  37.     for( i = 0; i < linesMax; i++ )  
  38.     {  
  39.         CvLinePolar line;  
  40.         int idx = sort_buf[i];  
  41.         int n = cvFloor(idx*scale) - 1;  
  42.         int r = idx - (n+1)*(numrho+2) - 1;  
  43.         line.rho = (r - (numrho - 1)*0.5f) * rho;  
  44.         line.angle = n * theta;  
  45.         cvSeqPush( lines, &line );  
  46.     }  

 

arrow
arrow
    全站熱搜

    Rocky 發表在 痞客邦 留言(0) 人氣()