MATLAB的邊緣檢測函數computeEdgesWithThinning中隱含的細化(非極大值抑制)算法


轉自:http://www.cnblogs.com/heleifz/archive/2013/10/27/3391225.html

這個函數matlab中處理的時候,檢測二維碼時能夠去除很多雜點,其調用的邊緣檢測算法中就包含這個方法,留着備用吧.該算法的原理如下:

通過對梯度圖進行非極大值抑制,得到梯度圖的掩膜圖,然后該圖上為1並且原前景點的梯度值大於設置的閾值時,才會保留。

 

前段時間做了一個車牌檢測識別的項目,我的任務是將MATLAB中的算法移植成C++代碼。在車牌區域提取的過程中,用到了水平方向的Sobel算子檢測垂直邊緣,一開始我直接把MATLAB中的

bw = edge(I, 'sobel', 'vertical');

語句改寫成OpenCV中的

cv::Mat sobel_kernel = (cv::Mat_<float>(3,3) << -0.125, 0, 0.125,
                                                -0.25, 0, 0.25,
                                                -0.125, 0, 0.125);
cv::Mat edges;
cv::filter2D(gray_img, edges, gray_img.type(), sobel_kernel);

之后,整個檢測算法產生了一些意想不到的輸出。追根溯源,我發現問題的根源就是在這個邊緣檢測步驟里:MATLAB的edge函數產生的是一個細化的二值邊緣,而OpenCV中輸出的是模板卷積后的浮點型的梯度值,若直接對其閾值化,將產生一個粗邊緣,如下圖所示(從左到右分別為edge函數輸出邊緣,OpenCV中直接使用Sobel算子及閾值化產生的邊緣,原圖)

研究了一下edge的實現代碼,我發現這么一個函數

 

computeEdgesWithThinning函數實現了非極大值抑制和閾值化的效果,這個函數的實現方式已經被MATLAB封裝,無法查看。一番波折之后,我模擬出一個效果基本一致的細化及閾值化算法(默認的閾值T為4乘以每個點梯度的模的平方的均值):

設 M(i, j) 為某點的梯度的模的平方
M(i, j) 大於閾值 T 且:
若 M(i, j) > M(i - 1, j) 且 M(i, j) > M(i + 1, j)  
或者 M(i, j) > M(i, j - 1) 且 M(i, j) > M(i, j + 1)
則將輸出邊緣圖像的 (i, j) 位置設為 1 

簡要地說,就是判斷一個點的梯度是否是水平或者垂直方向的上的局部極大值,當然,梯度值首先得大於閾值。經過實驗,加上這個非極大值抑制的步驟后,輸出圖片與MATLAB的edge函數產生的邊緣圖片基本一致,下面整個邊緣檢測加細化的MATLAB實現代碼(只檢測垂直的邊緣)

function e = sobel_thin(img)
op = fspecial('sobel') / 8; 
x_mask = op'; 
a = im2double(img);
scale = 4; 
bx = imfilter(a,x_mask,'replicate');
b = bx.*bx;
cutoff = 4 * mean2(b);
[m, n] = size(b);
 
for r = 1 : m
    for c=1 : n
        if ((c - 1) < 1)
            b1 = true;
        else
            b1 = (b(r, c - 1) <= b(r, c));
        end
        if (c + 1) > n
            b2 = true;
        else
            b2 = (b(r, c) > b(r, c + 1));
        end
        if ((r - 1) < 1)
            b3 = true;
        else
            b3 = (b(r - 1, c) <= b(r, c));
        end
        if ((r+1) > m)
            b4 = true;
        else
            b4 = (b(r, c) > b(r + 1, c));
        end
        e(r, c) = (b(r, c) > cutoff) &  ((b1 & b2) | (b3 & b4));
    end
end


免責聲明!

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



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