Part11. 圖像的輪廓
在該系列第三篇文章中,曾經簡單地介紹過輪廓和輪廓發現。
11.1 輪廓的基本概念
圖像的輪廓是指圖像中具有相同顏色或灰度值的連續點的曲線。輪廓和邊緣是有聯系的,邊緣是輪廓的基礎,輪廓是邊緣的連續集合。
輪廓和邊緣的區別是:
輪廓是連續的,邊緣可以是連續的,也可以是離散的。
輪廓是完整的,邊緣可以是完整的,也可以是不完整的。
輪廓可以有各種形狀,邊緣通常是線性的。
21.2 輪廓發現和輪廓提取
輪廓發現是指在圖像中找到所有可能的輪廓。
輪廓提取是指從圖像中找到所有有效的輪廓和輪廓的具體信息。
輪廓發現是輪廓提取的前提,輪廓提取在輪廓發現的基礎上進一步提取輪廓的形狀和位置信息等等。
下面的代碼,經過一系列操作找到二值圖像的有效輪廓后,獲取這些輪廓的最小外接矩形,最后用線在原圖中框出這些外接矩形,從而在原圖中找到比較明顯的蘋果。
#include#include"opencv2/imgproc.hpp" #include"opencv2/highgui.hpp" usingnamespacestd; usingnamespacecv; boolascendSort(vector a,vector b) { returncontourArea(a)>contourArea(b); } intmain(intargc,char**argv){ Matsrc=imread(".../apple.jpg"); imshow("src",src); Mathsv,edge; cvtColor(src,hsv,cv::COLOR_BGR2HSV);//BGR轉換到HSV色彩空間 imshow("hsv",hsv); cv::Scalarlower_red(0,43,46); cv::Scalarupper_red(10,255,255);//定義紅色的HSV范圍 Matmask; inRange(hsv,lower_red,upper_red,mask);//通過inRange函數實現二值化 imshow("mask",mask); Matkernel=getStructuringElement(MORPH_RECT,Size(15,15)); morphologyEx(mask,mask,MORPH_CLOSE,kernel);//形態學操作 morphologyEx(mask,mask,MORPH_OPEN,kernel);//形態學操作 imshow("morphology",mask); vector >contours; vector hierarchy; findContours(mask,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE); sort(contours.begin(),contours.end(),ascendSort);//ascendingsort for(size_ti=0;i
展示原圖
將原圖轉換成 HSV 類型,用于提取特定顏色。
hsv.png
通過 inRange 函數實現二值化。inRange 函數用于將圖像中的像素值限制在指定的范圍內,它會將滿足條件的像素設置為 255,不滿足條件的像素設置為 0,從而形成一個二值圖像。
二值化.png
對二值圖像進行一些形態學的操作,便于后續的輪廓分析。
形態學操作.png
通過 findContours() 函數進行輪廓發現。最后,篩選出有效的輪廓,并獲取最小外接矩形,用線畫出在原圖上展示出來。
Part22. 輪廓特征的分類
圖像的輪廓特征可以分為以下幾類:
基礎特征:面積、周長、質心、凸包、最小外接矩形等。這些特征可以直接從輪廓序列中計算得到。
矩特征:Hu 矩、中心矩、慣性矩等。這些特征可以用于描述輪廓的形狀和大小。
幾何特征:最小閉合圓、擬合橢圓等。這些特征可以用于描述輪廓的幾何形狀。
Part33. 輪廓的基礎特征
33.1 面積、周長、最小外接矩形
輪廓面積 contourArea()
輪廓周長 arcLength()
輪廓外接矩形 boundingRect()
輪廓最小外接矩形 minAreaRect()
下面的例子獲取圖中回形針的輪廓,以及輪廓的面積、周長、最小外接矩形等。
#include#include"opencv2/imgproc.hpp" #include"opencv2/highgui.hpp" usingnamespacestd; usingnamespacecv; boolascendSort(vector a,vector b) { returncontourArea(a)>contourArea(b); } intmain(intargc,char**argv){ Matsrc=imread(".../paperclip.jpg"); imshow("src",src); Matgray,thresh; cvtColor(src,gray,cv::COLOR_BGR2GRAY); imshow("gray",gray); threshold(gray,thresh,0,255,THRESH_BINARY_INV|THRESH_OTSU); imshow("thresh",thresh); vector >contours; vector hierarchy; findContours(thresh,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE); sort(contours.begin(),contours.end(),ascendSort);//ascendingsort for(size_ti=0;i
執行結果:
area=101573,length=2461.71 area=41757.5,length=1256.08 area=41348,length=1152.56 area=39717.5,length=1616.13 area=37503,length=1230.47 area=36742.5,length=1037.21 area=4142,length=706.357
外接矩形是指可以包圍輪廓所有點的矩形,而最小外接矩形是指包含輪廓中所有點的最小矩形。
下面的例子,獲取圖中最大輪廓的外接矩形和最小外接矩形,分別用黃色和藍色表示。
#include"opencv2/imgproc.hpp" #include"opencv2/highgui.hpp" usingnamespacestd; usingnamespacecv; boolascendSort(vectora,vector b) { returncontourArea(a)>contourArea(b); } intmain(intargc,char**argv){ Matsrc=imread(".../fruit.jpg"); imshow("src",src); Matgray,thresh; cvtColor(src,gray,cv::COLOR_BGR2GRAY); threshold(gray,thresh,0,255,THRESH_BINARY|THRESH_OTSU); vector >contours; vector hierarchy; findContours(thresh,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE); sort(contours.begin(),contours.end(),ascendSort);//ascendingsort RotatedRectrrt=minAreaRect(contours[0]);//獲取最大輪廓的最小外接矩形 Point2fpt[4]; rrt.points(pt); line(src,pt[0],pt[1],Scalar(255,0,0),8,8); line(src,pt[1],pt[2],Scalar(255,0,0),8,8); line(src,pt[2],pt[3],Scalar(255,0,0),8,8); line(src,pt[3],pt[0],Scalar(255,0,0),8,8); Rectrect=boundingRect(contours[0]);//獲取最大輪廓的外接矩形 rectangle(src,rect,Scalar(0,255,255),8,8);//繪制外接矩形 imshow("result",src); waitKey(0); return0; }
通過上述例子可以看到,最小外接矩形能夠更精確地描述輪廓的形狀和大小。
外接矩形和最小外接矩形有各自的使用場景,例如在對象檢測中,可以使用外接矩形來粗略定位物體,而使用最小外接矩形來精確定位物體。
43.2 凸包
凸包(Convex Hull)是計算幾何(圖形學)中的概念。在一個實數向量空間 V 中,對于給定集合 X,所有包含 X 的凸集的交集 S 被稱為 X 的 凸包。
在二維歐幾里得空間中,凸包可想象為一條剛好包著所有點的橡皮圈。
平面的一個子集 S 被稱為是“凸”的,當且僅當對于任意兩點 p,s ∈S,線段 ps 都完全屬于S。
一個點集 P 的凸包CH(P),就是包含 P 的最小凸集——即包含P的所有凸集的交。
凸包的性質:
凸包是凸集。
凸包的周長是最小的。
凸包的面積是最小的。
凸包的質心是所有點的質心的均值。
OpenCV 提供了 convexHull() 函數尋找輪廓的凸包以及 isContourConvex() 函數用于判斷輪廓是否為凸輪廓。凸輪廓是指所有內角都小于或等于 180 度的輪廓。
#include#include"opencv2/imgproc.hpp" #include"opencv2/highgui.hpp" usingnamespacestd; usingnamespacecv; intmain(intargc,char**argv){ Matsrc=imread(".../hand.jpg"); imshow("src",src); Matgray,thresh; cvtColor(src,gray,cv::COLOR_BGR2GRAY); threshold(gray,thresh,0,255,THRESH_BINARY_INV|THRESH_OTSU); imshow("thresh",thresh); Matmask; Matkernel=getStructuringElement(MORPH_RECT,Size(31,31)); morphologyEx(thresh,mask,MORPH_CLOSE,kernel);//形態學操作 imshow("morphology",mask); vector >contours; vector hierarchy; findContours(mask,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE); vector >hull(contours.size()); Matdrawing=Mat::zeros(mask.size(),CV_8UC3); for(size_ti=0;i
執行結果:
isHull=0 isHull=0
Part44. 總結
輪廓的基礎特征是計算機視覺中的重要工具,這些特征可以應用于對象檢測、形狀識別、測量等各種應用場景。后續還會介紹更多的輪廓特征。
審核編輯:湯梓紅
-
圖像
+關注
關注
2文章
1083瀏覽量
40449 -
代碼
+關注
關注
30文章
4779瀏覽量
68524 -
OpenCV
+關注
關注
31文章
634瀏覽量
41337
原文標題:OpenCV4之圖像的輪廓和輪廓的基礎特征
文章出處:【微信號:CVSCHOOL,微信公眾號:OpenCV學堂】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論