標籤:
當看到輪廓的時候,發現沒有辦法具體到什麼, 因為關係輪廓的東西似乎有很多,例如檢測輪廓,提取輪廓,輪廓跟蹤,輪廓面積,周長,標記,匹配,還有一系列的外接最小矩形,圓形,橢圓,映像矩,填充孔洞等,不得不說東西真的很好。
輪廓其實最容易和邊緣檢測聯絡到一起,有很多的相同,但是我理解的是邊緣是檢測,是預先處理,而輪廓就可能是你要用的特徵。
一、函數:一個是找,一個是畫
<span style="font-size:18px;">void findContours//提取輪廓,用於提取映像的輪廓(InputOutputArray image,//輸入映像,必須是8位單通道映像,並且應該轉化成二值的OutputArrayOfArrays contours,//檢測到的輪廓,每個輪廓被表示成一個point向量OutputArray hierarchy,//可選的輸出向量,包含映像的拓撲資訊。其中元素的個數和檢測到的輪廓的數量相等int mode,//說明需要的輪廓類型和希望的傳回值方式int method,//輪廓近似方法Point offset = Point())</span>
注意:mode輪廓檢索模式
CV_RETR_EXTERNAL 只檢測出最外輪廓即c0。圖2中第一個輪廓指向最外的序列,除此之外沒有別的串連。
CV_RETR_LIST 檢測出所有的輪廓並將他們儲存到表(list)中,圖2中描繪了這個表,被找到的9條輪廓相互之間由h_prev和h_next串連。這裡並沒有表達出縱向的串連關係,沒有使用v_prev和v_next.
CV_RETR_COMP 檢測出所有的輪廓並將他們組織成雙層的結構,第一層是外部輪廓邊界,第二層邊界是孔的邊界。從圖2可以看到5個輪廓的邊界,其中3個包含孔。最外層邊界c0有兩個孔,c0之間的所有孔相互間由h_prev和h_next指標串連。
CV_RETR_TREE 檢測出所有輪廓並且重建立立網狀的輪廓結構。圖2中,根節點是最外層的邊界c0,c0之下是孔h00,在同一層中與另一個孔h01相串連。同理,每個孔都有子節點(相對於c000和c010),這些子節點和父節點被垂直串連起來。這個步驟一直持續到映像最內層的輪廓,這些輪廓會成為樹分葉節點。
注意,method 也就是輪廓的近似方法
CV_CHAIN_CODE 用freeman鏈碼輸出輪廓,其他方法輸出多邊形(頂點的序列)。
CV_CHAIN_APPROX_NONE將鏈碼編碼中的所有點轉換為點。
CV_CHAIN_APPROX_SIMPLE壓縮水平,垂直或斜的部分,只儲存最後一個點。
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_QPPROX_TC89_KCOS使用Teh-Chin鏈逼近演算法中的一個。
CV_LINK_RUNS與上述的演算法完全不同,串連所有的水平層次的輪廓。
<span style="font-size:18px;">void drawContours//繪製輪廓,用於繪製找到的映像輪廓( InputOutputArray image,//要繪製輪廓的映像 InputArrayOfArrays contours,//所有輸入的輪廓,每個輪廓被儲存成一個point向量 int contourIdx,//指定要繪製輪廓的編號,如果是負數,則繪製所有的輪廓 const Scalar& color,//繪製輪廓所用的顏色 int thickness = 1, //繪製輪廓的線的粗細,如果是負數,則輪廓內部被填充 int lineType = 8, /繪製輪廓的線的連通性 InputArray hierarchy = noArray(),//關於層級的選擇性參數,只有繪製部分輪廓時才會用到 int maxLevel = INT_MAX,//繪製輪廓的最進階別,這個參數只有hierarchy有效時候才有效 //maxLevel=0,繪製與輸入輪廓屬於同一等級的所有輪廓即輸入輪廓和與其相鄰的輪廓 //maxLevel=1, 繪製與輸入輪廓同一等級的所有輪廓與其子節點。 //maxLevel=2,繪製與輸入輪廓同一等級的所有輪廓與其子節點以及子節點的子節點 Point offset = Point())</span>
具體的用法
<span style="font-size:18px;">#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>using namespace cv;using namespace std;#define WINDOW_NAME1 "【原始圖視窗】"#define WINDOW_NAME2 "【輪廓圖】"Mat g_srcImage; Mat g_grayImage;int g_nThresh = 80;int g_nThresh_max = 255;RNG g_rng(12345);Mat g_cannyMat_output;vector<vector<Point>> g_vContours;vector<Vec4i> g_vHierarchy;void on_ThreshChange(int, void* );int main( int argc, char** argv ){g_srcImage = imread( "lena.jpg", 1 );if(!g_srcImage.data ) { printf("讀取圖片錯誤,請確定目錄下是否有imread函數指定的圖片存在~! \n"); return false; } cvtColor( g_srcImage, g_grayImage, COLOR_BGR2GRAY );blur( g_grayImage, g_grayImage, Size(3,3) );namedWindow( WINDOW_NAME1, WINDOW_AUTOSIZE );imshow( WINDOW_NAME1, g_srcImage );//建立捲軸並初始化createTrackbar( "canny閾值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange );on_ThreshChange( 0, 0 );waitKey(0);return(0);}void on_ThreshChange(int, void* ){Canny( g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh*2, 3 );imshow("1",g_cannyMat_output);// 尋找輪廓findContours( g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );// 繪出輪廓Mat drawing = Mat::zeros( g_cannyMat_output.size(), CV_8UC3 );for( int i =0; i< g_vContours.size(); i++ ){Scalar color = Scalar( g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255) );//任意值drawContours( drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point() );}// 顯示imshow( WINDOW_NAME2, drawing );}</span>
二、其他的函數
- 返回外部矩形邊界 boundingRect()
- 尋找最小包圍矩形minA熱aRect()
- 尋找最小包圍圓形minEnclosingCircle()
- 橢圓擬合二維點集 fitEllipse()
- 逼近多邊形曲線approxPolyDP()
- 尋找凸包 convexHull()
- 映像的矩 moments
- 輪廓面積 contourArea
- 輪廓曲線長度 arcLength
三、matlab
regionprops統計被標記的地區的面積分布,顯示地區總數。這個裡面有多的不能再多的好用
函數regionprops文法規則為:STATS = regionprops(L,properties)
該函數用來測量標註矩陣L中每一個標註地區的一系列屬性。
- ‘Area‘ 映像各個地區中像素總個數
- ‘BoundingBox‘ 包含相應地區的最小矩形
- ‘Centroid‘ 每個地區的質心(重心)
- ‘MajorAxisLength‘ 與地區具有相同標準二階中心矩的橢圓的長軸長度(像素意義下)
- ‘MinorAxisLength‘ 與地區具有相同標準二階中心矩的橢圓的短軸長度(像素意義下)
- ‘Eccentricity‘ 與地區具有相同標準二階中心矩的橢圓的離心率(可作為特徵)
- ‘Orientation‘ 與地區具有相同標準二階中心矩的橢圓的長軸與x軸的交角(度)
- ‘Image‘ 與某地區具有相同大小的邏輯矩陣
- ‘FilledImage‘ 與某地區具有相同大小的填充邏輯矩陣
- ‘FilledArea‘ 填充地區映像中的on像素個數
- ‘ConvexHull‘ 包含某地區的最小凸多邊形
- ‘ConvexImage‘ 畫出上述地區最小凸多邊形
- ‘ConvexArea‘ 填充地區凸多邊形映像中的on像素個數
- ‘EulerNumber‘ 幾何拓撲中的一個拓撲不變數——歐拉數
- ‘Extrema‘ 八方向地區極值點
- ‘EquivDiameter‘ 與地區具有相同面積的圓的直徑
- ‘Solidity‘ 同時在地區和其最小凸多邊形中的像素比例
- ‘Extent‘ 同時在地區和其最小邊界矩形中的像素比例
- ‘PixelIdxList‘ 儲存地區像素的索引下標
- ‘PixelList‘ 儲存上述索引對應的像素座標
<span style="font-size:18px;">im=imread('d:\lena.jpg'); %讀取原圖figure,imshow(im,[]);title('Raw'); %顯示原圖im=im2bw(im); %轉二值映像figure,imshow(im,[]),title('BW'); %顯示二值映像im2=imfill(im,'holes'); %填充im3=bwperim(im2); %輪廓提取figure,imshow(im2,[]); title('') %顯示figure,imshow(im3,[]);</span>
OpencvImage Recognition從零到精通(23)----輪廓