計算機視覺 OpenCV Android | 特征檢測與匹配之角點檢測——Harris角點檢測與Shi-Tomasi角點檢測

本文要點總結(jié)(倆算法的聯(lián)系與區(qū)別)

Harris角點檢測與Shi-Tomasi角點檢測都是經(jīng)典的角點特征提取算法饰抒,
但兩者在API的使用上有出入(詳見文中代碼或GitHub項目)掠兄;

  • Harris角點檢測的API朱监,返回/輸出的是一個與輸入圖像大小一致的Mat對象禽笑,
    這個Mat對象每一個坐標(biāo)(i目代,j)都是對應(yīng)輸入圖像對應(yīng)坐標(biāo)(i靴迫,j)像素響應(yīng)值R
    要先將這個Mat對象歸一化盐碱,
    再循環(huán)每一個Mat數(shù)據(jù)元素瘩例,一 一 跟自己設(shè)置的閾值進行比較,
    合格的再認(rèn)為是角點提取出來甸各,
    進行繪制和保存垛贤;

  • Harris角點輸出不同,shi-tomasi簡單多了趣倾,
    直接輸出一個包含若干個(具體個數(shù)通過API形參設(shè)置)角點坐標(biāo)的角點數(shù)組聘惦,(其數(shù)據(jù)類型是MatOfPoint
    省略了很多步驟;
    遍歷這個角點數(shù)組,
    繪制出每個角點即可善绎。



引子

  • 前面兩章筆記(圖像操作黔漂、基本特征檢測
    主要講述了OpenCV中圖像處理模塊的主要知識與API使用;

  • 本章的筆記記錄OpenCV中另外一個重要模塊——feature2d模塊禀酱,
    該模塊的主要功能檢測圖像的特征炬守,
    根據(jù)特征進行對象匹配

  • 首先剂跟,關(guān)于圖像的特征减途,
    簡單地說,特征就是邊緣曹洽、角點鳍置、紋理等。

  • 本章會筆記特征提取送淆、檢測與匹配相關(guān)的知識與API税产,
    包括角點特征檢測、特征點檢測偷崩、特征描述子提取辟拷,
    以及根據(jù)特征描述子去匹配、尋找特征對象阐斜。

  • 本章知識會涉及較多的數(shù)學(xué)知識與公式衫冻,
    我們可以閱讀一些與特征提取相關(guān)的數(shù)學(xué)知識
    比如導(dǎo)數(shù)與微分智听、多項式與高斯公式曲線擬合羽杰,三角函數(shù),矩陣的特征值與特征向量的簡單計算等基礎(chǔ)數(shù)學(xué)知識到推,
    以更好地掌握本章知識以及各個API參數(shù)意義與用法考赛。



0 角點的定義與作用

基本特征檢測一章中,學(xué)習(xí)了關(guān)于邊緣檢測的知識莉测,
圖像邊緣中颜骤,有一些特殊的像素點值得我們特別關(guān)注,
那就是圖像邊緣的角點捣卤,
這些角點更能反映出圖像中對象的整體特征忍抽,
基于角點周圍的像素塊生成特征描述子可以更好地表述圖像特征數(shù)據(jù)

本文首先筆記如何提取圖像的角點特征董朝。

1 Harris角點檢測

關(guān)于角點特征提取最經(jīng)典的算法之一就是Harris角點檢測鸠项。

Harris角點檢測基本原理是對圖像求導(dǎo),對每個像素點生成二階梯度圖像子姜,
只是在卷積核使用的時候需要使用高斯核祟绊,
得到圖像X與Y方向的二階矩
基于它們就可以得到如下Hessian矩陣

求得最大兩個特征值 λ1 與 λ2,可以得到如下 角點響應(yīng)值R

其中牧抽,系數(shù)K常見的取值范圍為0.02~0.04嘉熊。

  • 每個像素點有自己的一個響應(yīng)值R
    也即有自己的一對特征值 λ1 與 λ2扬舒;
  • 全局像素則有多個R值阐肤;

根據(jù)M計算可以得到特征值 λ1、λ2讲坎,它們的值與角點的關(guān)系如下圖:

Harris角點檢測的API:

  • cornerHarris(Mat src, Mat dst, int blockSize, int ksize, double k)
    src:單通道的8位或者浮點數(shù)圖像孕惜,用灰度圖像;
    dst:輸出的每個像素點的響應(yīng)值衣赶,是CV_32F類型诊赊,大小與輸入圖像一致厚满。
    blockSize:根據(jù)特征值與特征向量計算矩陣M的大小府瞄,常見取值為2
    ksize Sobel:算子梯度計算碘箍,常見取值為3遵馆。
    k:系數(shù)大小,取值范圍為0.02~0.04丰榴。

使用Harris角點檢測函數(shù)計算得到圖像角點的演示代碼如下:

private void harrisCornerDemo(Mat src, Mat dst) {
  // 定義閾值T//初始化各種Mat對象
  int threshold = 100;
  Mat gray = new Mat();
  Mat response = new Mat();
  Mat response_norm = new Mat();

  // 角點檢測
  Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);//轉(zhuǎn)灰度;醯恕O乙丁U俦摺?茬浴P胶茫舶!
  Imgproc.cornerHarris(gray, response, 2, 3, 0.04);
  Core.normalize(response, response_norm, 0, 255, Core.NORM_MINMAX, CvType.CV_32F);//歸一化

  // 繪制角點
  dst.create(src.size(), src.type());
  src.copyTo(dst);
  float[] data = new float[1];//3婀 7孔省6犹痢T省>蹩浴!F偷恕O侍病!节值!
  for(int j=0; j<response_norm.rows(); j++ )
  {
    for(int i=0; i<response_norm.cols(); i++ )
    {
      response_norm.get(j, i, data);
      if((int)data[0] > 100)
      {
        Imgproc.circle(dst, new Point(i, j), 5, new Scalar(0, 0, 255), 
2, 8, 0);
        Log.i("Harris Corner", "find corner point……");
      }
    }
  }
  gray.release();
  response.release();
}
  • response_norm歸一化后的響應(yīng)值Mat對象
  • data[0]是某個響應(yīng)值徙硅;
    >100認(rèn)為其是一個較大的響應(yīng)值,
    響應(yīng)值大于指定閾值T(這里是100)搞疗,則對應(yīng)的像素點被認(rèn)為是角點嗓蘑;
  • float[] data = new float[1] //在這里,可能有人有疑問, 數(shù)組長度只有 1
    get()方法脐往,第三個參數(shù)要求是數(shù)組休吠,
    get多個像素時,傳入一個多元素空數(shù)組业簿,常規(guī)理解操作瘤礁;
    但當(dāng)只要get一個像素,則需創(chuàng)建一個只有一個元素的數(shù)組梅尤!而非變量柜思!

    這種接口設(shè)計思想
    一個方法(如get())接口即可實現(xiàn)包含一到多個數(shù)據(jù)元素的形式參數(shù)的傳入巷燥;
    而沒必要去準(zhǔn)備/重載兩個方法——
    一個用來接收包含單個數(shù)據(jù)元素的變量型形參赡盘,
    另一個用來接收包含多個數(shù)據(jù)元素的數(shù)組型形參;沒必要這樣了缰揪;

    即無論是負(fù)責(zé)接收數(shù)據(jù)的形參是包含 單個數(shù)據(jù)元素 還是 多個數(shù)據(jù)元素 陨享,一律按 數(shù)組型形參 處理,把數(shù)據(jù)形參位定義成數(shù)組類型钝腺,接口統(tǒng)一設(shè)計抛姑,一套代碼,一個接口即可艳狐,省時省力定硝!
  • 上述程序首先把彩色RGB圖像轉(zhuǎn)換為單通道灰度圖像,
    然后使用Harris角點檢測函數(shù)完成各個像素點上角點響應(yīng)值的計算毫目,
    最后使用閾值過濾繪制那些響應(yīng)值R比較大的像素點(角點)蔬啡。

注意,閾值T與繪制檢測得到的角點數(shù)目相關(guān)镀虐,
T值越大箱蟆,被過濾的響應(yīng)像素點越多,留下來的就越可能是角點粉私,反之亦然顽腾。

本章完整代碼在文末GitHub里邊的Feature2dMainActivity.java文件中,后續(xù)對此不再說明诺核。

2 Shi-Tomasi角點檢測

還有一種經(jīng)常使用的角點檢測方法稱為Shi-Tomasi角點檢測抄肖,
其與Harris角點檢測類似,這種方法同樣是基于梯度圖像發(fā)展而來的窖杀,
它是1994年由兩位作者Jianbo Shi與Carlo Tomasi一起提出來的漓摩,
他們當(dāng)時所發(fā)表的論文名為<<Good Feature to Track>>,
這也是為什么在OpenCV中使用同名函數(shù)來表示Shi-Tomasi角點檢測的原因入客。

Shi-Tomasi角點檢測與Harris角點檢測唯一(指的是方法邏輯管毙,不包括API腿椎,API的輸出還不同) 不同的地方在于計算角點響應(yīng)R值時使用的是如下方法:

如果R大于指定閾值T,則對應(yīng)的像素點被認(rèn)為是角點夭咬;
假設(shè)λ1啃炸、λ2為坐標(biāo),
則對角點的描述就是當(dāng)λ1卓舵、λ2都大于閾值T=λmin的右上角時南用,
角點響應(yīng)值滿足要求的區(qū)域,
如下圖:

相關(guān)的API如下:

  • goodFeaturesToTrack(Mat image, MatOfPoint corners, int maxCorners, double qualityLevel, double minDistance, Mat mask, int blockSize, boolean useHarrisDetector, double k)
    image:表示輸入圖像掏湾、類型為單通道的8位或浮點數(shù)裹虫,用灰度圖像
    corners:輸出得到角點數(shù)組融击,注意數(shù)據(jù)類型筑公;
    maxCorners:表示獲取前N個最強響應(yīng)R值的角點。
    qualityLevel:其取值范圍為0~1尊浪,這里取它與最大R值相乘匣屡,得到的值作為閾值T,低于它的都要被丟棄际长,
          假設(shè)Rmax=1500耸采,qualityLevel=0.01兴泥,則閾值T=15工育,小于15的角點都會被丟棄。

每個像素點有自己的一個響應(yīng)值R搓彻,去全局像素最大的R為Rmax如绸;

minDistance最終返回的角點之間的最小距離,小于這個距離則的角點被丟棄旭贬。
 mask:默認(rèn)全部為零怔接。
 blockSize:計算矩陣M時需要的,常取值為3稀轨。
 useHarrisDetector:是否使用Harris角點檢測扼脐,true表示使用,若為false則使用Shi-Tomasi角點檢測奋刽。
 k:當(dāng)使用Harris角點檢測的時候才使用瓦侮。

實現(xiàn)shi-tomasi角點檢測的demo:

private void shiTomasicornerDemo(Mat src, Mat dst) {

  // 變量定義
  double k = 0.04;
  int blockSize = 3;
  double qualityLevel= 0.01;
  boolean useHarrisCorner = false;

  // 角點檢測
  Mat gray = new Mat();
  Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
  MatOfPoint corners = new MatOfPoint();
  Imgproc.goodFeaturesToTrack(gray, corners, 100, qualityLevel, 10, new Mat(), blockSize, useHarrisCorner, k);

  // 繪制角點
  dst.create(src.size(), src.type());
  src.copyTo(dst);
  Point[] points = corners.toArray();
  for(int i=0; i<points.length; i++) {
    Imgproc.circle(dst, points[i], 5, new Scalar(0, 0, 255), 2, 8, 0);
  }
  gray.release();
}

完整的代碼可參考GitHub項目。


參考材料
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佣谐,一起剝皮案震驚了整個濱河市肚吏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狭魂,老刑警劉巖罚攀,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件党觅,死亡現(xiàn)場離奇詭異,居然都是意外死亡斋泄,警方通過查閱死者的電腦和手機杯瞻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炫掐,“玉大人又兵,你說我怎么就攤上這事∽浞希” “怎么了沛厨?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摔认。 經(jīng)常有香客問我逆皮,道長,這世上最難降的妖魔是什么参袱? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任电谣,我火速辦了婚禮,結(jié)果婚禮上抹蚀,老公的妹妹穿的比我還像新娘剿牺。我一直安慰自己,他們只是感情好环壤,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布晒来。 她就那樣靜靜地躺著,像睡著了一般郑现。 火紅的嫁衣襯著肌膚如雪湃崩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天接箫,我揣著相機與錄音攒读,去河邊找鬼。 笑死辛友,一個胖子當(dāng)著我的面吹牛薄扁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播废累,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼邓梅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了九默?” 一聲冷哼從身側(cè)響起震放,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎驼修,沒想到半個月后殿遂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诈铛,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年墨礁,在試婚紗的時候發(fā)現(xiàn)自己被綠了幢竹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡恩静,死狀恐怖焕毫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情驶乾,我是刑警寧澤邑飒,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站级乐,受9級特大地震影響疙咸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜风科,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一撒轮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贼穆,春花似錦题山、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至崖蜜,卻和暖如春浊仆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背豫领。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舔琅,地道東北人等恐。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像备蚓,于是被迫代替她去往敵國和親课蔬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容