Android基于OpenCV實現(xiàn)Harris角點檢測
什么是角點?
角點就是極值點,即在某方面屬性特別突出的點。當然,你可以自己定義角點的屬性(設(shè)置特定熵值進行角點檢測)。角點可以是兩條線的交叉處,也可以是位于相鄰的兩個主要方向不同的事物上的點。角點通常被定義為兩條邊的交點,或者說,角點的局部鄰域應(yīng)該具有兩個不同區(qū)域的不同方向的邊界。常見的角點有:
- 灰度梯度的最大值對應(yīng)的像素點;
- 兩條直線或者曲線的交點;
- 一階梯度的導(dǎo)數(shù)最大值和梯度方向變化率最大的像素點;
- 一階導(dǎo)數(shù)最大,二階導(dǎo)數(shù)為零的像素點(指示物體邊緣變化不連續(xù)的方向)。
為什么要檢測角點?
角點是圖像很重要的特征,對圖像圖形的理解和分析有很重要的作用。角點在保留圖像圖形重要特征的同時,可以有效地減少信息的數(shù)據(jù)量,使其信息的含量很高,有效地提高了計算的速度,有利于圖像的可靠匹配,使得實時處理成為可能。角點在三維場景重建、運動估計、目標跟蹤、目標識別、圖像配準與匹配等計算機視覺領(lǐng)域起著非常重要的作用。
Harris角點檢測
人眼對角點的識別通常是在一個局部的小區(qū)域或小窗口完成的。如果在各個方向上移動這個特征的小窗口,窗口內(nèi)區(qū)域的灰度發(fā)生了較大的變化,那么就認為在窗口內(nèi)遇到了角點。如果這個特定的窗口在圖像各個方向上移動時,窗口內(nèi)圖像的灰度沒有發(fā)生變化,那么窗口內(nèi)就不存在角點;如果窗口在某一個方向移動時,窗口內(nèi)圖像的灰度發(fā)生了較大的變化,而在另一些方向上沒有發(fā)生變化,那么,窗口內(nèi)的圖像可能就是一條直線的線段。
Harris角點檢測原理用公式演算如下:
其中w(x,y)表示滑動窗口權(quán)重函數(shù),可以是常數(shù)也可以是高斯函數(shù)。E(u,v)表示滑動窗口向各個方向移動時像素值衡量系數(shù)的變化。
這里λ1,λ2是矩陣M的2個特征值,k是一個指定值,這是一個經(jīng)驗參數(shù),需要實驗確定它的合適大小,通常它的值在0.04和0.06之間,它的存在只是調(diào)節(jié)函數(shù)的形狀而已。R取決于M的特征值,對于角點|R|很大,平坦的區(qū)域|R|很小,邊緣的R為負值;
API
public static void cornerHarris(Mat src, Mat dst, int blockSize, int ksize, double k, int borderType)
- 參數(shù)一:src,輸入源圖像。必須是單通道8U或者32F類型。
- 參數(shù)二:dst,輸出評價系數(shù)R的矩陣。尺寸與src相同,類型為單通道32F。
- 參數(shù)三:blockSize,鄰域大小。
- 參數(shù)四:ksize,Sobel算子的半徑。
- 參數(shù)五:k,計算Harris評價系數(shù)R的權(quán)重系統(tǒng)。
- 參數(shù)六:borderType,像素外推算法標志位。
方法的輸出dst為評價系數(shù)R的矩陣,由于評價系數(shù)有正有負且范圍較廣,計算結(jié)束后通常需要進行歸一化處理。然后通過經(jīng)驗閾值比較判斷像素點是否為Harris角點。閾值越大,提取的Harris角點越少,閾值越小,提取的Harris角點越多。
操作
/** * Harris角點檢測 * author: yidong * 2020/12/30 */ class HarrisActivity : AppCompatActivity() { private val mBinding: ActivityHarrisBinding by lazy { ActivityHarrisBinding.inflate(layoutInflater) } private val gray by lazy { this.getBgrFromResId(R.drawable.lena).toGray() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(mBinding.root) mBinding.ivLena.showMat(gray) wrapCoroutine({ showLoading() }, { doCornerHarris() }, { hideLoading() }) } private fun doCornerHarris() { val dst = Mat() val dstNorm = Mat() val dstNormal8U = Mat() Imgproc.cornerHarris(gray, dst, 2, 3, 0.04) Core.normalize(dst, dstNorm, 0.0, 255.0, Core.NORM_MINMAX) Core.convertScaleAbs(dstNorm, dstNormal8U) Imgproc.threshold(dstNormal8U, dstNormal8U, 120.0, 255.0, Imgproc.THRESH_BINARY) GlobalScope.launch(Dispatchers.Main) { mBinding.ivResult.showMat(dstNormal8U) } } private fun showLoading() { mBinding.isLoading = true } private fun hideLoading() { mBinding.isLoading = false } override fun onDestroy() { super.onDestroy() gray.release() } }
效果
如下圖,圖中白點即為評價系數(shù)大于120的角點檢測結(jié)果。代碼中的參數(shù)可自行調(diào)整測試。
源碼
以上就是Android基于OpenCV實現(xiàn)Harris角點檢測的詳細內(nèi)容,更多關(guān)于Android OpenCV實現(xiàn)Harris角點檢測的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
不允許錯過的Anndroid技術(shù)經(jīng)驗60條
不允許錯過的Anndroid技術(shù)經(jīng)驗60條,與大家分享,希望可以提高大家Android開發(fā)水平,感興趣的朋友可以參考一下2016-02-02淺談Android性能優(yōu)化之內(nèi)存優(yōu)化
Android的內(nèi)存優(yōu)化是性能優(yōu)化中很重要的一部分,本文將詳細介紹Android性能優(yōu)化之內(nèi)存優(yōu)化。2021-06-06Android編程之ProgressBar圓形進度條顏色設(shè)置方法
這篇文章主要介紹了Android編程之ProgressBar圓形進度條顏色設(shè)置方法,涉及ProgressBar布局及屬性設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2017-02-02