


void cv::findContours(
cv::InputOutputArray image, // 輸入圖像,特別需要注意是二值圖像
cv::OutputArrayOfArrays contours, //輸出結果
cv::OutputArray hierarchy, // 層級結果
int mode, //定義輪廓是如何提取
int method, // 定義輪廓的尋找方法
cv::Point offset = cv::Point() // Offset every point
);
參數一:輸入圖像,8位單通道;
參數二:“an array of arrays”,一般采用“ an STL vector of STL vectors”,找到的輪廓、函數調用后的運算結果保存在這里;
參數三:hierarchy(層次,等級),可選輸出向量。包含圖像的拓撲信息。每個輪廓對應4元組,分別對應后一個輪廓、前一個輪廓、父輪廓和內嵌輪廓。
參數四:flag 輪廓檢索模式
參數五:flag 輪廓近似方法
Index
|
Meaning
|
0
|
同級的下一條輪廓
|
1
|
同級的前一條輪廓
|
2
|
下級的第一個子節點
|
3
|
上級的父節點
|

0 [ 7, -1, 1, -1]
1 [-1, -1, 2, 0]
2 [-1, -1, 3, 1]
3 [-1, -1, 4, 2]
4 [-1, -1, 5, 3]
5 [ 6, -1, -1, 4]
6 [-1, 5, -1, 4]
7 [ 8, 0, -1, -1]
8 [-1, 7, -1, -1]
cv::CHAIN_APPROX_NONE
將輪廓編碼中的所有點轉換為點。 這一操作將會產生大量的點,每個點都將成為前一個點的8個鄰點之一, 不會減少返回的點數,
cv::CHAIN_APPROX_SIMPLE
壓縮水平、垂直、斜的部分,只保留最后一個點。 在許多特殊情況下,這一操作將大大減少返回的點數。 極端例子是,對於一個沿着x-y x-y 軸方向的矩形(任意大小), 只會返回4個點。
cv::CHAIN_APPROX_TC89_L1 or cv::CHAIN_APPROX_TC89_KCOS
double cv::arcLength(
cv::InputArray points, // Array or vector of 2-dimensional points
bool closed // If true, assume link from last to first vertex
);
第一個參數代表是輪廓,其形式可以是任何常見的輪廓表示方法(如標准模板庫的點向量,或二通道數組)。
第二個參數closed表示該輪廓是否是閉合的。 假如輪廓是閉合的,則參數points中的最后一個點到第一個的距離也算入總弧長中。
cv::RotatedRect cv::minAreaRect( // Return rectangle bounding the points
cv::InputArray points, // Array or vector of 2-dimensional points
);
void cv::minEnclosingCircle(
cv::InputArray points, // Array or vector of 2-dimensional points
cv::Point2f& center, // Result location of circle center
float& radius // Result radius of circle
);
void cv::convexHull(
cv::InputArray points, // Array or vector of 2-d points
cv::OutputArray hull, // Array of points or integer indices
bool clockwise = false, // true='output points will be clockwise'
bool returnPoints = true // true='points in hull', else indices
);
double cv::pointPolygonTest( // Return distance to boundary (or just side)
cv::InputArray contour, // Array or vector of 2-dimensional points
cv::Point2f pt, // Test point
bool measureDist // true 'return distance', else {0,+1,-1} only
);
與輪廓分析緊密相關的另一種方法是連通區域分析. 采用閾值化等方法分割一張圖像后,我們可以采用連通區域分析來有效地對返回圖像逐張分離和處理。在以前,常用的方法是”是先調用 cv::findContours() 函數(傳入cv::RETR_CCOMP 標志),隨后在得到的連通區域上循環調用 cv::drawContours() “
//尋找最大的輪廓
VP FindBigestContour(Mat src){
int
imax
=
0
;
//代表最大輪廓的序號
int
imaxcontour
=
-
1
;
//代表最大輪廓的大小
std
:
:
vector
<
std
:
:
vector
<
Point
>>
contours;
findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
for
(
int
i
=
0
;i
<
contours.size();i
++
){
int
itmp
=
contourArea(contours[i]);
//這里采用的是輪廓大小
if
(imaxcontour
<
itmp ){
imax
=
i;
imaxcontour
=
itmp;
}
}
return
contours[imax];
}
//尋找並繪制出彩色聯通區域
vector
<
VP
>
connection2(Mat src,Mat
&
draw){
draw
=
Mat
:
:
zeros(src.rows,src.cols,CV_8UC3);
vector
<
VP
>
contours;
findContours(src.clone(),contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
//由於給大的區域着色會覆蓋小的區域,所以首先進行排序操作
//冒泡排序,由小到大排序
VP vptmp;
for
(
int
i
=
1
;i
<
contours.size();i
++
){
for
(
int
j
=
contours.size()
-
1
;j
>
=
i;j
--
){
if
(contourArea(contours[j])
<
contourArea(contours[j
-
1
]))
{
vptmp
=
contours[j
-
1
];
contours[j
-
1
]
=
contours[j];
contours[j]
=
vptmp;
}
}
}
}
int cv::connectedComponents (
cv::InputArrayn image, // input 8-bit single-channel (binary)
cv::OutputArray labels, // output label map
int connectivity = 8, // 4- or 8-connected components
int ltype = CV_32S // Output label type (CV_32S or CV_16U)
);
int cv::connectedComponentsWithStats (
cv::InputArrayn image, // input 8-bit single-channel (binary)
cv::OutputArray labels, // output label map
cv::OutputArray stats, // Nx5 matrix (CV_32S) of statistics:[x0, y0, width0, height0, area0;... ; x(N-1), y(N-1), width(N-1),height(N-1), area(N-1)]
cv::OutputArray centroids, // Nx2 CV_64F matrix of centroids:[ cx0, cy0; ... ; cx(N-1), cy(N-1)]
int connectivity = 8, // 4- or 8-connected components
int ltype = CV_32S // Output label type (CV_32S or CV_16U)
);

5.1什么是矩(moment)
數學定義:實函數相對於值c的n階矩為
從上述公式可以看到,它就是一個加了權重的積分,而權重是(x-c)n,其中n是階數(n階矩),如果把它想成一個平面直角系中,c是x軸上的一點,(x-c)n是個x點相對於c點值的n次方。以下是個積分的圖示,只要想象一下,它的每個小方塊再乘上權重:(xi-c)^n即可得到矩。
輪廓處理中用到的矩,是它在統計學中的應用。
以上公式是一元的情況,擴展到圖片所在的二元,想象我們有一個圖像矩陣,經過了尋找邊緣,轉換輪廓之后,矩陣中每個值點f(x,y)的值或為0(不是輪廓點),或為1(是輪廓點),當f(x,y)為0時,該積分項也為0,可以不計算,因此,對我們有意義的只有f(x,y)=1的n個點,即輪廓點。在后面公式中記為I(x,y),x,y為其在圖中的坐標,c點擴展到二元,可以視為輪廓的中心點,我們求得的所謂n階中心矩,就如上述公式所示,積分的權重是輪廓上各點相對於中心位置c的n次方。
此時我們可以得到一些統計規律,比如:輪廓邊界長度(零階矩),x/y方向上的均值(即質心,由一階矩求得),方差(由二階中心矩求得),形狀特性(Hu矩)
5.2. 常用的矩
1) 空間矩(spatial moment)
i. 用途
最簡單地輪廓比較,只能用於對比位置,大小,角度完全一致的輪廓。一般來說輪廓矩代表了一條輪廓、一幅圖像、一組點集的某些高級特征。
ii. 公式

在上式中,mp,q代表對象中所有像素的總和,其中每個像素x, y的像素值都乘以因子 xpyq。. 在m00時,這個因子等於1。因此若圖像為二值圖(如,所有像素都等於0或者1),則 m00代表圖像上所有值非零的區域。 當處理輪廓時,結果是輪廓的長度。
中心矩常用μp, q標注,定義如下
其中:

