Android智慧識別 - 銀行卡區域裁剪(原理篇)
在 Android智慧識別 - 銀行卡區域裁剪 一文中我們用瞭如下幾行程式碼,獲取發現銀行卡的輪廓:
// 梯度增強 , x 軸和 y 軸 Mat grad_x, grad_y; Scharr(blur, grad_x, CV_32F, 1, 0); Scharr(blur, grad_y, CV_32F, 0, 1); Mat grad_abs_x, grad_abs_y; convertScaleAbs(grad_x, grad_abs_x); convertScaleAbs(grad_y, grad_abs_y); Mat grad; addWeighted(grad_abs_x, 0.5, grad_abs_y, 0.5, 0, grad);
輪廓發現是影象圖形處理中最常見的一個操作,Opencv 到底提供了哪些輪廓檢測的方法?其內部的實現原理是怎樣的?為啥我在上面要用 Scharr ?下面我們就來做一個徹底的刨析。
Opencv 為我們提供了常用的四個方法 Sobel() Scharr() Laplacian() Canny() 用來處理邊緣檢測,當然還可以自定義卷積操作來實現,但這裡我們先不做考慮。
1. Sobel 運算元

X和Y方向

對X\Y兩個方向的梯度進行合併
Sobel運算元如果光從核上面去看,根本什麼都不知道,我們得去看他的原理。

他的原理就是利用導數求解邊緣,我們知道畫素差別大的時候那麼它的切點越陡峭,那麼這個時候就找到了邊緣!Sobel 運算元檢測方法對灰度漸變和噪聲較多的影象處理效果較好,但 Sobel 運算元對邊緣定位不是很準確,影象的邊緣不止一個畫素。
2. Scharr 運算元
這個濾波是Sobel的升級版,原理是一樣的,就是實現的近似代替不一樣,說白了就事核改進了。

3. Laplacian 運算元

拉普拉斯運算元

拉普拉斯邊緣檢測是通過二階倒數,從上面的一階倒數的理解就不難發現二階倒數是怎麼進行的了。二階倒數比一階倒數的好處是在與受到周圍的干擾小,其不具有方向性,操作容易,且對於很多方向的影象處理好。Laplacian 運算元法對噪聲比較敏感,所以很少用該運算元檢測邊緣,而是用來判斷邊緣畫素視為與影象的明區還是暗區。
4. Canny 運算元
這是比較新的演算法,運用的也是最廣泛的。Canny的步驟是:
1.給一張圖片,先進行濾波消除干擾,濾波之前已經說明。
2.計算梯度(進行 Sobel/Scharr 運算元)
3.非極大值抑制。
4.滯後閾值。
非極大值抑制: 從字面上的理解就是從一群資料中找到真正的極大值,對於不是極大值的省略或者抑制顯示。我們來想一下,Sobel運算元計算的值就是邊緣的值嗎?運算元是固定的,那就有很大的機率會計算到不是邊緣的資料。計算的結果不會省略不好的點,也不會去加強好的點,所以顯示就不明顯。我們的目的就是改進上面兩個點,對於第一個點,我們得比較那些計算的點進行比較,把不好點捨去。高等數學中有 “梯度” 的這個概念,就是資料下降或者上升最快的方向,簡單的說就是求導切線的方向!
void Canny(InputArray image, // 輸入 OutputArray edges,// 輸出 double threshold1, // 低閾值 double threshold2, // 高閾值 int apertureSize = 3, // 卷積核大小 bool L2gradient = false );// 採用何種方式做梯度合併
視訊地址: https://pan.baidu.com/s/1BHGR6hcunmgS5m_NGK_x2Q
視訊密碼:dtvq