


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)
);
矩的数值定义如下式:

在上式中,mp,q代表对象中所有像素的总和,其中每个像素x, y的像素值都乘以因子 xpyq。. 在m00时,这个因子等于1。因此若图像为二值图(如,所有像素都等于0或者1),则 m00代表图像上所有值非零的区域。 当处理轮廓时,结果是轮廓的长度。
将m10和m01分别除以 m00,能得到整个对象的平均x值和y值。

中心矩常用μp, q标注,定义如下
其中:
原文:https://www.cnblogs.com/jsxyhelu/p/13228159.html