Android開發中的OpenCV霍夫直線檢測(Imgproc.HoughLines()&Imgproc.HoughLinesP())


本文為作者原創,轉載請注明出處(http://www.cnblogs.com/mar-q/)by 負贔屓
 
//2017-04-21更新:
很多網友希望能得到源碼,由於在公司做的,所以不太方便傳出來。而且我估計很多人可能都是對OpenCV在AndroidStudio環境下配置的問題,給大家推薦一本書《Mastering OpenCV Android Application Programming》,中文版叫《深入OpenCV Android應用開發》,某寶有賣正版,書中有詳細代碼(第二章有霍夫變換),可以到www.packtpub.com下載,如果不會可以私信郵箱給我,我可以發鏈接給你。
 
霍夫檢測是Paul Hough1962年提出的圖像中幾何圖形識別算法,霍夫線檢測是基於圖像二值化的變換,利用二值化圖像中的點集合來發現候選直線集合。原理是利用坐標空間變換,將笛卡爾坐標系(直角坐標系)下的點(圖1)映射到極坐標系(圖2),這種點到曲線的映射變換稱為霍夫變換,對極坐標進行峰值統計,對統計規則滿足直線要求的點進行歸類。
(圖1)
(圖2)
 
(圖3)
 
(圖4)
      如圖1,直角坐標系中直線方程表示為:y = kx+b,其中的一個點(x0,y0)映射到極坐標中表示為:r = cos(θ)*x0 + sin(θ )*y0,r是半徑,θ是角度,當x0和y0確定時,可以出現很多滿足條件的r和θ,如果將圖繪制出來就是圖2的弦波。多個點就會出現多個弦波,交點存在唯一的r0和θ0,對應到直角坐標系即圖4的直線,滿足r0和θ0的點即為一條直線。
      Opencv提供了兩種霍夫線檢測算法:HoughLines和HoughLinesP,在Android中Java代碼為:
HoughLines(Mat image, Mat lines, double rho, double theta, int threshold, double srn, double stn)
HoughLinesP(Mat image, Mat lines, double rho, double theta, int threshold, double minLineLength, double maxLineGap)
image:輸入圖像,要求必須是二值化圖像,通常是用canny后的圖片作為輸入圖;
lines:輸出結果,在HoughLines方法中,輸出結果是(r,θ),lines是1行(row)n列(col)的Mat,通過get(0,i)可以獲取到(r,θ)數組;在HoughLinesP方法中,輸出結果是P1(x1,y1),P2(x2,y2),即端點的坐標值,lines是1行(row)n列(col)的Mat,通過get(0,i)可以獲取到(x1, y1, x2, y2)數組;
rho:極坐標系中半徑r的搜索步長(累加值),如果為1表示每次累計1個像素;
theta:極坐標系中角度θ的搜索步長,通常設置為π/180,表示每次累加角度為π/180;
threshold:累加器的閾值參數,只有滿足閾值數量的點的直線才會被檢測出來;
srn/stn:對於多尺度霍夫變換,rho為極坐標系中累加值的粗粒度表示,srn/stn為細粒度的累加值;
minLineLength:HoughLinesP方法中,只有長度超過minLineLength的線段才能被檢測出來;
maxLineGap:HoughLinesP方法中,線段跨越的最大空隙為maxLineGap。
 
// Opencv在Android中,大部分的vector、指針、數組都是以Mat來呈現的
Imgproc.HoughLinesP(matIn, line, 1, Math.PI / 180, 20, 150, 10);
if (line.rows() > 0 && line.cols() > 0) {
    for (int i = 0; i < line.cols(); i++) {
        double[] l = line.get(0, i);
        if (l.length == 4) {
            if (Math.abs(l[1] - l[3]) < 2) {
                Point p1 = new Point(l[0], l[1]);
                Point p2 = new Point(l[2], l[3]);
                Core.line(matIn, p1, p2, new Scalar(255, 255, 255), 2);
            }
        }
    }
}
注意Mat變量的結構,通過get(x,y)獲取坐標點值,坐標點的各通道在java中通過數組呈現。
 
//2017-04-06更新
忘記說檢測效果了,首先一定要先canny,針對圖片的檢測問題還是不大的,但是在實時camera的場景下,檢測到的直線是跳躍的,尤其是在復雜背景下,不要奢望能夠得到一條穩定的直線。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM