計(jì)算機(jī)視覺(jué) OpenCV Android | 基本特征檢測(cè) 之 輪廓分析

(0)輪廓分析概述及作用

  • 通過(guò)將Canny邊緣提取或者二值化結(jié)果作為輸入圖像來(lái)實(shí)現(xiàn)輪廓發(fā)現(xiàn)與繪制废封,
    可是這些并不是我們想要的最終結(jié)果

    我們一般根據(jù)獲取到的輪廓求出它們的外接矩形或者最小外接矩形
    并計(jì)算外接矩形橫縱比例钮科、輪廓面積退盯、周長(zhǎng)等數(shù)據(jù)

    然后使用這些數(shù)據(jù)實(shí)現(xiàn)特定幾何形狀輪廓查找與過(guò)濾撤师,
    后續(xù)的處理與分析剔除不正確的區(qū)域保留候選對(duì)象剂府。
(1)邊界框
  • 最常見(jiàn)的獲取輪廓的外接矩形邊界框
    獲取每個(gè)輪廓的邊界框丈氓,
    通過(guò)可以得到與各個(gè)輪廓相對(duì)應(yīng)的高度與寬度周循,
    并能通過(guò)它計(jì)算出輪廓的縱橫比

通過(guò)輪廓點(diǎn)集合得到輪廓邊界框的API如下:

boundingRect(MatOfPoint points)

其中万俗,points輪廓所有點(diǎn)的集合對(duì)象湾笛。注意其數(shù)據(jù)類型。

調(diào)用該API會(huì)返回一個(gè)Rect對(duì)象實(shí)例闰歪,它是OpenCV關(guān)于矩形的數(shù)據(jù)結(jié)構(gòu)嚎研,
從中可以得到外界矩形(邊界框)的寬高
然后就可以計(jì)算出輪廓的橫縱比了库倘。

這種情況下得到的邊界框不一定滿足條件临扮,有時(shí)候我們還需要獲取輪廓的最小邊界框

(2)最小邊界框

與上面邊界框不同的是教翩,
獲取到的最小邊界框有時(shí)候不是一個(gè)水平或者垂直的矩形杆勇,
而是一個(gè)旋轉(zhuǎn)了一定角度的矩形

但是最小外接矩形(最小邊界框)能夠更加真實(shí)地反映出輪廓的幾何結(jié)構(gòu)大小饱亿,
橫縱比結(jié)果更能反映出輪廓的真實(shí)幾何特征蚜退,
所以有些時(shí)候我們計(jì)算的經(jīng)常最小外接矩形闰靴,

相關(guān)API函數(shù)如下:

RotatedRect minAreaRect(MatOfPoint2f points)

其中,points是輪廓的所有點(diǎn)的集合對(duì)象钻注。注意其數(shù)據(jù)類型蚂且。

  • 調(diào)用該API會(huì)返回一個(gè)RotatedRect對(duì)象實(shí)例
    它是OpenCV關(guān)于旋轉(zhuǎn)矩形的數(shù)據(jù)結(jié)構(gòu)幅恋,
    其包含了旋轉(zhuǎn)角度杏死,矩形的寬、高及四個(gè)頂點(diǎn)等信息捆交,
    通過(guò)相關(guān)的API都可以查詢獲得淑翼,

    繪制旋轉(zhuǎn)矩形對(duì)象的時(shí)候,
    首先需要得到四個(gè)頂點(diǎn)零渐,
    然后通過(guò)OpenCV繪制直線的API來(lái)完成旋轉(zhuǎn)矩形的繪制窒舟。
(3)面積與周長(zhǎng)
  • 輪廓分析中包含了輪廓大小的度量
    這些度量最常見(jiàn)的就是計(jì)算輪廓的面積大小長(zhǎng)度大小诵盼,

    這些數(shù)據(jù)對(duì)分析輪廓過(guò)濾掉一些不符合條件的輪廓十分有用惠豺。

計(jì)算輪廓面積的API如下:

contourArea(Mat contour, boolean oriented)

contour:輪廓的所有點(diǎn)集合對(duì)象
oriented:表示輪廓的方向风宁,當(dāng)oriented = true時(shí)返回的面積是一個(gè)有符號(hào)值洁墙,默認(rèn)為false,返回的是絕對(duì)值戒财。

計(jì)算輪廓周長(zhǎng)的API如下:

arcLength(MatOfPoint2f curve, boolean closed)

curve:輪廓的所有點(diǎn)集合對(duì)象热监。注意數(shù)據(jù)類型。
closed:表示是否為閉合曲線饮寞,默認(rèn)是true孝扛。

完整的發(fā)現(xiàn)獲取輪廓、外接輪廓幽崩、最小外接輪廓苦始、橫縱比、面積與長(zhǎng)度的代碼演示如下:

private void measureContours(Mat src, Mat dst) {
  Mat gray= new Mat();
  Mat binary = new Mat();

  // 二值
  Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
  Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);

  // 輪廓發(fā)現(xiàn)
  List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
  Mat hierarchy = new Mat();
  Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));

  // 測(cè)量輪廓
  dst.create(src.size(), src.type());
  for(int i=0; i<contours.size(); i++) {
      Rect rect = Imgproc.boundingRect(contours.get(i));
      double w = rect.width;
      double h = rect.height;
      double rate = Math.min(w, h)/Math.max(w, h);
    Log.i("Bound Rect", "rate:" + rate);//一個(gè)輪廓元素打印一次

    RotatedRect minRect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
    w = minRect.size.width;
    h = minRect.size.height;
    rate = Math.min(w, h)/Math.max(w, h);
    Log.i("Min Bound Rect", "rate:" + rate);

    double area = Imgproc.contourArea(contours.get(i), false);
    double arclen = Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()), true);
    Log.i("contourArea", "area:" + rate);
    Log.i("arcLength", "arcLength:" + arclen);
    Imgproc.drawContours(dst, contours, i, new Scalar(0, 0, 255), 1);
  }

  // 釋放內(nèi)存
  gray.release();
  binary.release();
}

運(yùn)行結(jié)果(左側(cè)是原圖慌申,右側(cè)是輪廓發(fā)現(xiàn)與繪制陌选,計(jì)算結(jié)果參見(jiàn)logcat):

上述的代碼是求取圖像的全部輪廓
修改上述程序蹄溉,把返回輪廓改為返回最外層輪廓RETR_EXTERNAL咨油,
同時(shí)修改閾值化方法,將其改為THRESH_BINARY_INV柒爵,
則運(yùn)行結(jié)果如下:

  • 感興趣的小伙伴可以進(jìn)一步細(xì)化該方法役电,
    將計(jì)算得到的輪廓幾何屬性值如長(zhǎng)度、面積等
    通過(guò)putText函數(shù)顯示到輸出的圖像上



參考材料
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末棉胀,一起剝皮案震驚了整個(gè)濱河市法瑟,隨后出現(xiàn)的幾起案子囱晴,更是在濱河造成了極大的恐慌,老刑警劉巖瓢谢,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異驮瞧,居然都是意外死亡氓扛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門论笔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)采郎,“玉大人,你說(shuō)我怎么就攤上這事狂魔∷饴瘢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵最楷,是天一觀的道長(zhǎng)整份。 經(jīng)常有香客問(wèn)我,道長(zhǎng)籽孙,這世上最難降的妖魔是什么烈评? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮犯建,結(jié)果婚禮上讲冠,老公的妹妹穿的比我還像新娘。我一直安慰自己适瓦,他們只是感情好竿开,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著玻熙,像睡著了一般否彩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上揭芍,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天胳搞,我揣著相機(jī)與錄音,去河邊找鬼称杨。 笑死肌毅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的姑原。 我是一名探鬼主播悬而,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼锭汛!你這毒婦竟也來(lái)了笨奠?” 一聲冷哼從身側(cè)響起袭蝗,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎般婆,沒(méi)想到半個(gè)月后到腥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔚袍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年乡范,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啤咽。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晋辆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宇整,到底是詐尸還是另有隱情瓶佳,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布鳞青,位于F島的核電站霸饲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏盼玄。R本人自食惡果不足惜贴彼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望埃儿。 院中可真熱鬧器仗,春花似錦、人聲如沸童番。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)剃斧。三九已至轨香,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幼东,已是汗流浹背臂容。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留根蟹,地道東北人脓杉。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像简逮,于是被迫代替她去往敵國(guó)和親球散。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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