StupidBeauty
Read times:1971Posted at:Sun Nov 17 03:55:21 2013
- no title specified

OpenCV 2.4.7.0文档翻译:结构分析及形状描述器,Structural Analysis and Shape Descriptors

内容目录

findContours

drawContours

approxPolyDP

arcLength

contourArea

convexHull

isContourConvex

pointPolygonTest

findContours

在一张单色的图片中寻找轮廓。

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

参数:

  • •. image – 源图片,8位的单通道图片。非零的像素都会被当成1来处理。为零的像素会被当成0来处理,所以,这张图片会被当成单色( binary )图片来处理。妳可以使用 compare() inRange() threshold() adaptiveThreshold() Canny() 或别的什么函数来从一张灰度图片或彩色图片中转换出一张单色图片。这个函数在提取轮廓的同时也会修改图片(image)本身。

  • •. contours – 检测到的轮廓。每个轮廓都被储存成一个由点组成的向量。

  • •. hierarchy – 可选的输出向量,其中包含有该图片的拓扑信息。它的元素个数与轮廓的个数相等。对于每个下标为 i 的轮廓contours[i],对应的元素hierarchy[i][0]hiearchy[i][1]hiearchy[i][2]hiearchy[i][3]分别会被设置成contours 中元素的下标,并且其意义按照顺序就是:同一层级上的下一个及上一个轮廓的下标,第一个子代轮廓及它的亲代轮廓的下标。如果,对于下标为 i 的轮廓,没有下一个、上一个、亲代或嵌套的轮廓,则,hierarchy[i]中相应的元素会是负数。

  • •. mode

    轮廓的提取模式(如果妳使用Python,则还要看看下面的一条说明)。

    • •. CV_RETR_EXTERNAL 仅仅提取那些处于外围的轮廓。它会将所有轮廓的对应拓扑值设置成:hierarchy[i][2]=hierarchy[i][3]=-1

    • •. CV_RETR_LIST 提取所有的轮廓,但是不建立任何的层级关系。

    • •. CV_RETR_CCOMP 提取所有的轮廓,并且将它们组织成一个两层的层级关系。在顶上的一级中,包含的是图案中各个组件(components)的外边界(external boundaries)。在底下的一级中,包含的是图案中那些洞(holes)的边界(boundaries)。如果,在某个连通(connected)的组件(component)的一个洞(hole)中,还有另一个轮廓,则这个轮廓也会被放置到顶上那一级中去。

    • •. CV_RETR_TREE 提取所有的轮廓,并且为嵌套的轮廓构建一个完整的层级关系。在OpenCV contours.c 示例中,构建并显示了这个完整的层级关系。

  • •. method

    轮廓近似算法(如果妳使用Python,则还要看看下面的一条说明)。

    • •. CV_CHAIN_APPROX_NONE 精确地储存轮廓中所有的点。更具体点说,轮廓中每2个相邻的点, (x1,y1)(x2,y2),或者是水平的,或者是竖直的,或者是对角线上的相邻点,即,max(abs(x1-x2),abs(y2-y1))==1

    • •. CV_CHAIN_APPROX_SIMPLE 将水平、竖直及对角线的线段压缩,只保留它们的端点。例如,一个上右形(up-right)的矩形轮廓,是由4个点组成的。

    • •. CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 应用一种Teh-Chin 链式逼近算法。参考[TehChin89]以了解细节。

  • •. offset – 可选的偏移值,每个轮廓都会按照这个偏移值来修正位置。这个选项在这种情况下非常有用:轮廓是从图片的某个感兴趣区域(ROI)里提取出来的,而然后妳又需要在整张图片的范围内分析这些结果。

这个函数会按照[Suzuki85]算法来从一张单色图片里提取出轮廓。轮廓在形状分析、目标检测及识别中非常有用。参考OpenCV 示例目录中的squares.c

注意

这个函数会修改源图片(image)。并且,这个函数不会将图片四周边缘的1个像素计算在内(它们会被填充为0,并且在算法中被用于相邻点(neighbor)分析),所以,连接到图片边缘的那些轮廓会被裁剪掉一部分。

注意

如果妳使用的是新的Python 接口,那么,在轮廓提取模式和轮廓逼近方法参数中的CV_前缀应当去掉(例如,使用cv2.RETR_LISTcv2.CHAIN_APPROX_NONE作为参数)。如果妳使用的是旧的Python 接口,则,这些参数都要带上CV_前缀(例如,使用cv.CV_RETR_LISTcv.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

drawContours

绘制轮廓的形状(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

参数:

  • •. image – 目标图片。

  • •. contours – 所有的输入轮廓。每个轮廓都被储存成一个由点组成的向量。

  • •. contourIdx – 这个参数用来指定要绘制哪个轮廓。如果它是负数,则所有的轮廓都会被绘制。

  • •. color – 这些轮廓的颜色。

  • •. thickness – 用来绘制这些轮廓的线的宽度。如果它是负数(例如,thickness=CV_FILLED),则,这个轮廓的内部也会被填充。

  • •. lineType – 线的连接模式。参考 line() 以了解更多细节。

  • •. hierarchy – 关于层级关系的可选信息。仅仅当妳只想绘制其中某些轮廓时,这个参数才有用(参考maxLevel)。

  • •. maxLevel – 要绘制的轮廓的最大层级数。如果为0,则,只有指定的轮廓会被绘制。如果它为1,则,这个函数会绘制指定的轮廓及所有嵌套在它们内部的轮廓。如果它为2,则,这个函数会绘制指定的轮廓、它们的所有嵌套轮廓、以及嵌套轮廓的嵌套轮廓,如此下去。只有当妳设置了层级关系参数( hierarchy )时,这个参数才会被计算在内。

  • •. offset – 可选的轮廓偏移参数。按照指定的偏移值
    来将所有被绘制的轮廓偏移一个位置。
    来将所有被绘制的轮廓偏移一个位置。
  • •. contour – 指向第一个轮廓的指针。

  • •. externalColor – 外围(external)轮廓的颜色。

  • •. holeColor – 内部(internal)轮廓(洞(holes))的颜色。

如果 \texttt{thickness} \ge 0\texttt{thickness} \ge 0
,则这个函数在图片中绘制轮廓的形状(outlines),如果
\texttt{thickness}<0\texttt{thickness}<0
,则这个函数在图片中绘制出实心的轮廓。以下示例,演示了,如果从单色图片中提取出相连接的组件(connected components),并且标记它们:

#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

approxPolyDP

按照指定的精度来逼近一个多边形曲线。

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 )

参数:

  • •. curve

    输入向量,由二维点组成,以以下方式储存:

    • •. std::vectorMat (C++接口)

    • •. Nx2 numpy数组(Python接口)

    • •. CvSeq 或 `` CvMat (C接口)

  • •. approxCurve – 逼近的结果。它的类型应当与输入曲线的类型一致。对于C语言的接口,逼近得到的曲线是保存在内存存储(memory storage)里的,会返回指向它的一个指针。

  • •. epsilon – 这个参数,指定了逼近过程中采用的精度。它的意义就是,原始曲线与逼近结果之间的最大距离。

  • •. closed – 如果为真(true),则,逼近得到的曲线是闭合的(第一个点和最后一个点是连接的)。否则,就不是闭合的。

  • •. header_size – 逼近得到的曲线的数据头(Header)尺寸。一般情况下,可使用sizeof(CvContour)

  • •. storage – 用来保存逼近得到的曲线的内存存储。

  • •. method – 轮廓逼近算法。只支持CV_POLY_APPROX_DP

  • •. recursive – 递归标志。如果被设置为非零的值并且curve CvSeq*,则,cvApproxPoly 这个函数会利用h_next v_next 链接来对可从curve 访问到的所有轮廓做逼近计算。

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 以了解这个函数的用法。

contourArea

计算一个轮廓的面积。

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

参数:

  • •. contour – 输入的由二维点组成的向量(轮廓的节点), 以std::vector Mat 形式保存。

  • •. oriented – 方向判断标志位。如果为真,则,这个函数会返回一个带符号的面积值,具体的符号取决于这个轮廓的方向(顺时针还是逆时针)。妳可以利用这个功能来通过面积值的符号判断一个轮廓的方向。默认情况下,这个参数为假(false),意味着会返回绝对值。

这个函数计算一个轮廓的面积。与 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;

convexHull

找出一个点集合的凸多边形外壳(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

参数:

  • •. points – 输入的二维点集合,以std::vector Mat 的形式保存。

  • •. hull – 输出的凸多边形外壳。它可能是一个由索引下标组成的整数向量或是一个由点组成的向量。在第一种情况下,hull中的元素就是从0开始计数的索引,表示凸多边形外壳中节点在原始输入数组中的下标(因为凸多边形外壳中的点就是原始输入点集合的子集)。在第二种情况下, hull中的元素就表示着凸多边形外壳中的节点本身。

  • •. hull_storage – 在旧接口(API)中使用的输出内存存储(cvConvexHull2会返回一个序列,其中包含有凸多边形外壳中的点或者点的索引)。

  • •. clockwise – 方向性标志。如果为真,则输出的凸多边形外壳会是顺时针方向。否则,就是逆时针方向的。在假设的坐标系统中,X轴指向右方,Y轴指向上方。

  • •. orientation – 旧版接口中,凸多边形外壳的方向参数,CV_CLOCKWISECV_COUNTERCLOCKWISE

  • •. returnPoints – 操作标志位。对于一个矩阵,如果这个标志位为真,则,这个函数会返回凸多边形外壳中的点。否则,它返回凸多边形中的点的索引。如果输出的数组是std::vector,则这个标志位会被忽略,输出的具体类型取决于这个向量的类型:std::vector<int> 将导致returnPoints=truestd::vector<Point>将导致returnPoints=false

这个函数使用Sklansky 的算法 [Sklansky82] 来计算一个二维点集合的凸多边形外壳,当前的复杂度是 O(N logN) 。参考OpenCV 示例 convexhull.cpp ,它演示了使用这个函数的不同变种的方法。

注意

  • •.在这里可找到一个使用convexHull函数的示例 opencv_source_code/samples/cpp/convexhull.cpp

宇宙

卫星

飞机

Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands