
OpenCV 2.4.7.0文档翻译:结构分析及形状描述器,Structural Analysis and Shape Descriptors
在一张单色的图片中寻找轮廓。
C++: void findContours (InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
C++: void findContours (InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset=Point())
Python: cv2.findContours (image, mode, method[, contours[, hierarchy[, offset]]]) → contours, hierarchy
C: int cvFindContours (CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) )
Python: cv.FindContours (image, storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0, 0)) → contours
|
参数: |
|
这个函数会按照[Suzuki85]算法来从一张单色图片里提取出轮廓。轮廓在形状分析、目标检测及识别中非常有用。参考OpenCV 示例目录中的squares.c。
注意
这个函数会修改源图片(image)。并且,这个函数不会将图片四周边缘的1个像素计算在内(它们会被填充为0,并且在算法中被用于相邻点(neighbor)分析),所以,连接到图片边缘的那些轮廓会被裁剪掉一部分。
注意
如果妳使用的是新的Python 接口,那么,在轮廓提取模式和轮廓逼近方法参数中的CV_前缀应当去掉(例如,使用cv2.RETR_LIST和cv2.CHAIN_APPROX_NONE作为参数)。如果妳使用的是旧的Python 接口,则,这些参数都要带上CV_前缀(例如,使用cv.CV_RETR_LIST和cv.CV_CHAIN_APPROX_NONE)。
注意
•.可在这里找到一个使用findContour函数的示例 opencv_source_code/samples/cpp/contours2.cpp
•.可在这里找到一个使用findContours 来消除背景片断(segmentation)的示例 opencv_source_code/samples/cpp/segment_objects.cpp
•.(Python) 可在这里找到一个使用findContour函数的示例 opencv_source/samples/python2/contours.py
•.(Python) 可在这里找到一个检测图片中正方形的示例 opencv_source/samples/python2/squares.py
绘制轮廓的形状(outlines)或绘制整个实心(filled)轮廓。
C++: void drawContours (InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )
Python: cv2.drawContours (image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) → None
C: void cvDrawContours (CvArr* img, CvSeq* contour, CvScalar externalColor, CvScalar holeColor, int maxLevel, int thickness=1, int lineType=8 )
Python: cv.DrawContours (img, contour, external_color, hole_color, max_level, thickness=1, lineType=8, offset=(0, 0)) → None
|
参数: |
|
\texttt{thickness} \ge 0
\texttt{thickness}<0
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main( int argc, char** argv )
{
Mat src;
// 第一个命令行参数,并须是一个单色(黑白)图片的文件名
if( argc != 2 || !(src=imread(argv[1], 0)).data)
return -1;
Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
src = src > 1;
namedWindow( "Source", 1 );
imshow( "Source", src );
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( src, contours, hierarchy,
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
// 遍历所有的顶级轮廓,以随机颜色绘制每个连通组件
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0] )
{
Scalar color( rand()&255, rand()&255, rand()&255 );
drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy );
}
namedWindow( "Components", 1 );
imshow( "Components", dst );
waitKey(0);
}
注意
•.可在这里找到一个使用drawContour函数的示例 opencv_source_code/samples/cpp/contours2.cpp
•.可在这里找到一个使用drawContours来清除背景片断的示例 opencv_source_code/samples/cpp/segment_objects.cpp
•.(Python) 可在这里找到一个使用drawContour函数的示例 opencv_source/samples/python2/contours.py
按照指定的精度来逼近一个多边形曲线。
C++: void approxPolyDP (InputArray curve, OutputArray approxCurve, double epsilon, bool closed )
Python: cv2.approxPolyDP (curve, epsilon, closed[, approxCurve]) → approxCurve
C: CvSeq* cvApproxPoly (const void* src_seq, int header_size, CvMemStorage* storage, int method, double eps, int recursive=0 )
|
参数: |
|
approxPolyDP 函数,使用另一个节点较少的曲线/多边形来逼近指定的曲线或多边形,确保两者之间的距离小于等于指定的精度值。它使用的是Douglas-Peucker算法 http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
参考 http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/contours.cpp 以了解这个函数的用法。
计算一个轮廓的周长或一个曲线的长度。
C++: double arcLength (InputArray curve, bool closed )
Python: cv2.arcLength (curve, closed) → retval
C: double cvArcLength (const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 )
Python: cv.ArcLength (curve, slice=CV_WHOLE_SEQ, isClosed=-1) → float
|
参数: |
|
这个函数,计算一条曲线的长度或者是一个闭合的轮廓的周长。
计算一个轮廓的面积。
C++: double contourArea (InputArray contour, bool oriented=false )
Python: cv2.contourArea (contour[, oriented]) → retval
C: double cvContourArea (const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ, int oriented=0 )
Python: cv.ContourArea (contour, slice=CV_WHOLE_SEQ) → float
|
参数: |
|
这个函数计算一个轮廓的面积。与 moments() 类似,面积是使用Green 公式来计算的。所以,如果妳使用 drawContours() 或 fillPoly() 来绘制这个轮廓的话,所得到的非零像素点的个数可能与计算出来的面积值不同。另外,对于一个与自身相交的轮廓,这个函数极有可能计算出错误的结果。
示例:
vector<Point> contour;
contour.push_back(Point2f(0, 0));
contour.push_back(Point2f(10, 0));
contour.push_back(Point2f(10, 10));
contour.push_back(Point2f(5, 4));
double area0 = contourArea(contour);
vector<Point> approx;
approxPolyDP(contour, approx, 5, true);
double area1 = contourArea(approx);
cout << "area0 =" << area0 << endl <<
"area1 =" << area1 << endl <<
"approx poly vertices" << approx.size() << endl;
找出一个点集合的凸多边形外壳(convex hull)。
C++: void convexHull (InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true )
Python: cv2.convexHull (points[, hull[, clockwise[, returnPoints]]]) → hull
C: CvSeq* cvConvexHull2 (const CvArr* input, void* hull_storage=NULL, int orientation=CV_CLOCKWISE, int return_points=0 )
Python: cv.ConvexHull2 (points, storage, orientation=CV_CLOCKWISE, return_points=0) → convexHull
|
参数: |
|
这个函数使用Sklansky 的算法 [Sklansky82] 来计算一个二维点集合的凸多边形外壳,当前的复杂度是 O(N logN) 。参考OpenCV 示例 convexhull.cpp ,它演示了使用这个函数的不同变种的方法。
注意
•.在这里可找到一个使用convexHull函数的示例 opencv_source_code/samples/cpp/convexhull.cpp
测试一个轮廓是否为凸多边形。
C++: bool isContourConvex (InputArray contour )
Python: cv2.isContourConvex (contour) → retval
C: int cvCheckContourConvexity (const CvArr* contour )
Python: cv.CheckContourConvexity (contour) → int
|
参数: |
contour – 由二维点组成的输入向量,按照以下形式存储:
|
这个函数会测试输入的轮廓是否是凸多边形。这个轮廓必须是简单的,也就是说,自身并没有相交。否则,可能产生奇特的结果。
测试一个点是否是位于某个轮廓内部。
C++: double pointPolygonTest (InputArray contour, Point2f pt, bool measureDist )
Python: cv2.pointPolygonTest (contour, pt, measureDist) → retval
C: double cvPointPolygonTest (const CvArr* contour, CvPoint2D32f pt, int measure_dist )
Python: cv.PointPolygonTest (contour, pt, measure_dist) → float
|
参数: |
|
这个函数会计算出,一个点是在一个轮廓的内部、外部还是在某条边上(或与某个顶点重合)。对应地,会返回一个正数(在内部)、负数(在外部)或0值(在边上)。如果 measureDist=false ,则返回的值分别是+1、-1和0。否则,返回值就是一个带符号的距离,表示的是这个点到最近的轮廓边之间的距离。
以下是一个示例,图片中的每个点都与轮廓进行了一次测试。
../../../_images/pointpolygon.png
|
Sklansky, J., 计算一个简单多边形的凸多边形外壳。 PRL 1 $number, pp 79-83 (1982) |
宇宙
卫星
飞机
HxLauncher: Launch Android applications by voice commands