OpenCV-------drawContours函数解析

1、drawContours函数的作用

主要用于画出图像的轮廓

2、函数的调用形式

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() )

函数参数详解:

其中第一个参数image表示目标图像,

第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成,

第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,

第四个参数color为轮廓的颜色,

第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,

第六个参数lineType为线型,

第七个参数为轮廓结构信息,

第八个参数为maxLevel



opencv代码:

#include "cv.h"
#include "highgui.h"

using namespace cv;

int main( int argc, char** argv )
{
    Mat src;
    // the first command-line parameter must be a filename of the binary
    // (black-n-white) image
    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 );

    // iterate through all the top-level contours,
    // draw each connected component with its own random color
    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);
}


提取到轮廓后,其实我们更关心的是如果把这些轮廓转换为可以利用的特征,也就是涉及到轮廓的描述问题,这时就有多种方法可以选择,比如矢量化为多边形、矩形、椭圆等。OpenCV里提供了一些这样的函数。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 轮廓表示为一个矩形
Rect r = boundingRect(Mat(contours[0]));
rectangle(result, r, Scalar(255), 2);
 
// 轮廓表示为一个圆
float radius;
Point2f center;
minEnclosingCircle(Mat(contours[1]), center, radius);
circle(result, Point(center), static_cast < int >(radius), Scalar(255), 2);
 
// 轮廓表示为一个多边形
vector<Point> poly;
approxPolyDP(Mat(contours[2]), poly, 5, true );
vector<Point>::const_iterator itp = poly.begin();
while (itp != (poly.end() - 1))
{
     line(result, *itp, *(itp + 1), Scalar(255), 2);
     ++itp;
}
line(result, *itp, *(poly.begin()), Scalar(255), 2);
// 轮廓表示为凸多边形
vector<Point> hull;
convexHull(Mat(contours[3]), hull);
vector<Point>::const_iterator ith = hull.begin();
while (ith != (hull.end() - 1))
{
     line(result, *ith, *(ith + 1), Scalar(255), 2);
     ++ith;
}
line(result, *ith, *(hull.begin()), Scalar(255), 2);


对连通区域的分析到此远远没有结束,我们可以进一步计算每一个连通区域的其他属性,比如:重心、中心矩等特征,这些内容以后有机会展开来写。

以下几个函数可以尝试:minAreaRect:计算一个最小面积的外接矩形,contourArea可以计算轮廓内连通区域的面积;pointPolygenTest可以用来判断一个点是否在一个多边形内。mathShapes可以比较两个形状的相似性,相当有用的一个函数。


`drawContours()`函数OpenCV中的一个函数,用于在图像上绘制轮廓。该函数的定义如下: ```python cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None) ``` 其中,参数含义如下: - `image`:要绘制轮廓的图像,必须为8位无符号图像。 - `contours`:表示轮廓的列表。每个轮廓都是一个包含边界点的numpy数组。 - `contourIdx`:要绘制的轮廓的索引。当设置为-1时,绘制所有轮廓。 - `color`:绘制轮廓的颜色。 - `thickness`:轮廓线的粗细。默认值为1。 - `lineType`:轮廓线的类型。默认为`cv2.LINE_8`。 - `hierarchy`:轮廓的层次结构信息。默认为`None`。 - `maxLevel`:要绘制的轮廓的最大层次结构级别。默认为`None`。 - `offset`:轮廓偏移量。默认为`(0,0)`。 `drawContours()`函数可以用于在图像上绘制单个轮廓或多个轮廓。如果要绘制多个轮廓,需要将所有的轮廓放在一个列表中,然后将该列表作为`contours`参数传递给函数。如果要绘制所有轮廓,可以将`contourIdx`参数设置为-1。 例如,下面的代码演示了如何使用`drawContours()`函数在图像上绘制轮廓: ```python import cv2 # 读取图像 img = cv2.imread('test.jpg') # 将图像转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理 ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 获取轮廓 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 在图像上绘制轮廓 cv2.drawContours(img, contours, -1, (0, 255, 0), 2) # 显示图像 cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个例子中,我们首先将图像转换为灰度图像,然后对其进行二值化处理,接着使用`cv2.findContours()`函数获取轮廓。最后,我们使用`cv2.drawContours()`函数在图像上绘制轮廓,并将结果显示出来。 注意,`drawContours()`函数并不会修改传递给它的图像,而是返回一个绘制了轮廓的新图像。如果要修改原始图像,请将结果赋值给原始图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值