OpenCV绘图函数详解及其用法示例

        MFC类库中的CDC类有划线,画矩形,画椭圆,画多边形,文字等绘图函数,OpenCV也有类似的绘图函数。二者的区别在于MFC画图是在一定的区域内绘制图形,而OpenCV则是在图像上绘制,主要用于图像标注。

        OpenCV的常用绘图函数有arrowedLinecircle ,drawContours, drawMarker, drawMarker, ellipse,fillConvexPoly, fillPoly , line, polylines , putText ,rectangle 。下面详细介绍这些函数及其用法。

        arrowedLine()

        arrowedLine()函数的原型如下:

参数:
        img   装载有图像的Mat对象

        pt1    第一点

        pt2    第二点

        color  绘制箭头线段颜色

        thickness 圆形轮廓的厚度(如果为正)。负值(例如 FILLED)表示要绘制实心圆。

        line_Type 线的类型,有FILLED,LINE_4,LINE_8,LINE_AA几种.

        shift  点坐标中小数位数

        tipLength 箭头尖端的长度与箭头长度的比例关系

        用法示例

        新建一个控制台程序,在程序中加入如下代码:

#include <iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    //std::cout << "Hello World!\n";

    Mat bgn(Size(2048, 1024), CV_8UC3, Scalar(0)); 
    arrowedLine(bgn, Point(50, 50), Point(300, 100), Scalar(0, 0, 255), 2, 8, 0, 0.08);
    imshow("Background", bgn);



    waitKey(0);

    return 0;
}

试运行,结果如下:

circle()

        circle()函数的原型如下:

函数参数:

        img 图像,如载有图像的Mat对象

        center 圆心(点)

        color   颜色

        thickness 圆形轮廓的厚度(如果为正)。负值(例如 FILLED)表示要绘制实心圆。

        lineType 线条类型

        shift  中心坐标和半径值中的小数位数。

        示例程序

        上面程序中加入画圆代码,如下:

#include <iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    //std::cout << "Hello World!\n";

    Mat bgn(Size(2048, 1024), CV_8UC3, Scalar(0)); 
    arrowedLine(bgn, Point(50, 50), Point(300, 100), Scalar(0, 0, 255), 2, 8, 0, 0.08);
    circle(bgn, Point(200, 200), 100, Scalar(0, 0, 255), 2,8,0);
    imshow("Background", bgn);



    waitKey(0);

    return 0;
}

试运行,结果如下:

 

drawContours() 

        drawContours() 函数的原型如下:

函数参数:

image 图像

conturs 所有输入轮廓。每个轮廓存储为点向量

conturIdx 指示要绘制的轮廓的参数。如果为负数,则绘制所有轮廓

color 颜色

thickness 圆形轮廓的厚度(如果为正)。负值(例如 FILLED)表示要绘制实心圆。

lineType 线条类型

hierarchy 有关层次结构的可选信息。仅当您只想绘制一些轮廓时才需要它(请参阅 maxLevel )

maxLevel 绘制轮廓的最大级别。如果为0,则只绘制指定的轮廓。如果为 1,该函数将绘制轮廓               和所有嵌套轮廓。如果为 2,则该函数绘制轮廓、所有嵌套轮廓、所有嵌套到嵌套轮廓,               依此类推。仅当存在可用的层次结构时才考虑此参数。

offset  可选的轮廓移动参数。将所有绘制的轮廓移动指定的 offset=(dx,dy) 。 

        该函数绘制轮廓轮廓或填充轮廓。 如果厚度≥0,则该函数在图像中绘制轮廓轮廓;如果厚度<0,则填充轮廓所包围的区域。

        示例程序

修改上面的代码,如下:

#include <iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    //std::cout << "Hello World!\n";

    Mat bgn(Size(2048, 1024), CV_8UC3, Scalar(0)); 
    arrowedLine(bgn, Point(50, 50), Point(300, 100), Scalar(0, 0, 255), 2, 8, 0, 0.08);
    circle(bgn, Point(200, 200), 100, Scalar(0, 0, 255), 2,8,0);

    Mat src = imread("2.webp");
    if (src.empty())
        return -1;
    cvtColor(src, src, COLOR_BGR2GRAY);
    threshold(src, src, 235, 255, THRESH_BINARY_INV);
    imshow("Source", src);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(src, contours, hierarchy,
        RETR_CCOMP, CHAIN_APPROX_SIMPLE);
    int idx = 0;
    for (; idx >= 0; idx = hierarchy[idx][0])
    {
        Scalar color(rand() & 255, rand() & 255, rand() & 255);
        drawContours(bgn, contours, idx, color, FILLED, 8, hierarchy);
    }

    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

        试运行,结果如下:

drawMarker()

        drawMarker()函数的原型如下:

函数参数:

        img  图像

        position 十字准线的位置

        color 线条颜色

        markerType 您要使用的特定标记类型,缺省是十字标记,有以下几种类型:

        makerSize 标记轴的长度 [默认 = 20 像素]

        thickness 线条厚度,缺省是1

        lineType 线条类型,缺省是8

        该函数的作用是在图像中的预定义位置绘制标记。

        示例程序:

        在上面的示例程序中加入draw maker示例代码,如下:

#include <iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    //std::cout << "Hello World!\n";

    Mat bgn(Size(2048, 1024), CV_8UC3, Scalar(0)); 
    arrowedLine(bgn, Point(50, 50), Point(300, 100), Scalar(0, 0, 255), 2, 8, 0, 0.08); //draw arrow line
    circle(bgn, Point(200, 200), 100, Scalar(0, 0, 255), 2,8,0); //draw  circle

    Mat src = imread("2.webp");
    if (src.empty())
        return -1;
    cvtColor(src, src, COLOR_BGR2GRAY);
    threshold(src, src, 235, 255, THRESH_BINARY_INV);
    imshow("Source", src);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(src, contours, hierarchy,
        RETR_CCOMP, CHAIN_APPROX_SIMPLE);
    int idx = 0;
    RNG rng(0xFFFFFFFF);
    for (; idx >= 0; idx = hierarchy[idx][0])
    {
        drawContours(bgn, contours, idx, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), FILLED, 8, hierarchy);
    }

    drawMarker(bgn, Point(500, 500), Scalar(255), MARKER_STAR, 40, 4, 8); //draw maker
    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

试运行,结果如下:

 ellipse()

        ellipse()函数的原型有两个, 如下:

函数参数:

        img  图像

        center 椭圆的中心

        axes 椭圆长短主轴尺寸的一半

        angle 椭圆旋转角度(以度为单位)

        startAngle 椭圆弧的起始角度(以度为单位)

        endAngle  椭圆弧的结束角度(以度为单位)

        box 通过 RotatedRect 的替代椭圆表示。这意味着该函数绘制一个内切于该旋转矩形的椭                     圆。

        color 椭圆线条颜色

        thickness 椭圆弧轮廓的厚度(如果为正)。否则,这表明要绘制一个填充的椭圆扇区

        lineType 椭圆边界的类型。请参阅线型。

        示例程序

        在上面的示例程序中添加画椭圆的代码,如下:

#include <iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    //std::cout << "Hello World!\n";

    Mat bgn(Size(2048, 1024), CV_8UC3, Scalar(0)); 

    //draw arrow line
    arrowedLine(bgn, Point(50, 50), Point(300, 100), Scalar(0, 0, 255), 2, 8, 0, 0.08); 

    //draw  circle
    circle(bgn, Point(200, 200), 100, Scalar(0, 0, 255), 2,8,0); 

    //draw  conturs test
    Mat src = imread("2.webp");
    if (src.empty())
        return -1;
    cvtColor(src, src, COLOR_BGR2GRAY);
    threshold(src, src, 235, 255, THRESH_BINARY_INV);
    imshow("Source", src);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(src, contours, hierarchy,
        RETR_CCOMP, CHAIN_APPROX_SIMPLE);
    int idx = 0;
    RNG rng(0xFFFFFFFF);
    for (; idx >= 0; idx = hierarchy[idx][0])
    {
        drawContours(bgn, contours, idx, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), FILLED, 8, hierarchy);
    }

    //draw maker
    drawMarker(bgn, Point(500, 500), Scalar(255), MARKER_STAR, 40, 4, 8); 

    //draw ellipse
    ellipse(bgn, Point(500, 500), Size(400, 250), 0, 0, 360, Scalar(0,0,255),4, 8);
    ellipse(bgn, RotatedRect(Point2f(500,500),Size2f(300,100),45), Scalar(0, 255, 0), -1, 8);


    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

试运行,结果如下:

fillConvexPoly() 

        fillConvexPoly() 函数的原型有两个,如下:

函数参数:

        img 图像

        points 多边形顶点。

        pts 多边形的顶点的数组,其中每个多边形表示为点数组

        npts 顶点的个数

        color 多边形颜色

        lineType 多边形线型

        shift 顶点坐标中的小数位数

       函数 cv::fillConvexPoly 绘制填充的凸多边形。此函数比函数 fillPoly 快得多。它不仅可以填充凸多边形,还可以填充任何没有自交的单调多边形,即轮廓与每条水平线(扫描线)最多相交两次的多边形(尽管其最顶部和/或底部边缘可以是水平的)。

        示例程序

        在上面示例程序的main函数中加入fillConvexPoly的代码,如下:

    //fillConvexPoly
    Point pt;
    vector<Point2i> mpoints;
    Point pts[6];
    for (int i = 0; i < 18; i++)
    {
        pt.x = 1300 + 300 * cos(20 * i * CV_PI / 180);
        pt.y = 500 + 300 * sin(20 * i * CV_PI / 180);
        mpoints.push_back(pt);
    }
    for (int i = 0; i < 6; i++)
    {
        pt.x = 1300 + 200 * cos(60 * i * CV_PI / 180);
        pt.y = 500 + 200 * sin(60 * i * CV_PI / 180);
        pts[i] = pt;
    }
    fillConvexPoly(bgn, mpoints,Scalar(255,0,0));
    fillConvexPoly(bgn, pts, 6,Scalar(255, 0, 255));


    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

试运行,结果如下:

fillPoly()

        fillPoly函数的原型函数如下:

函数参数:

        img 图像

        pts 多边形顶点

        color 多边形颜色

        lineType 多边形线型

        shift 顶点坐标中的小数位数。

        offset 轮廓所有点的可选偏移。

        函数 fillPoly 填充由多个多边形轮廓界定的区域。该函数可以填充复杂区域,例如,有孔的区域、具有自相交的轮廓(其中的某些部分)等等。

        示例程序

        在上面的示例程序中加入fillPoly代码, 如下:

    //fillPoly
    mpoints.clear();
    for (int i = 0; i < 9; i++)
    {
        pt.x = 1000 + 100 * cos(40 * i * CV_PI / 180);
        pt.y = 300 + 100 * sin(40 * i * CV_PI / 180);
        mpoints.push_back(pt);
    }
    fillPoly(bgn, mpoints, Scalar(0, 255, 0));

    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

试运行,结果如下:

line()

        line()函数的原型如下:

函数参数:

        pt1 第一个点

        p2 第二个点

        color 线段颜色

        thickness 线条厚度,缺省值为1

        lineType 线的类型,缺省值为8

        shift 点坐标中小数位数

     函数 line 在图像中绘制 pt1 和 pt2 点之间的线段。该线被图像边界剪裁。对于具有整数坐标的非抗锯齿线,使用 8 连接或 4 连接 Bresenham 算法。粗线以圆角结尾绘制。抗锯齿线是使用高斯滤波绘制的。

        示例程序:

        在上面的示例程序中加入 line演示代码,如下:

    //fillPoly
    mpoints.clear();
    for (int i = 0; i < 9; i++)
    {
        pt.x = 1000 + 100 * cos(40 * i * CV_PI / 180);
        pt.y = 300 + 100 * sin(40 * i * CV_PI / 180);
        mpoints.push_back(pt);
    }
    fillPoly(bgn, mpoints, Scalar(0, 255, 0));

    //line
    line(bgn, Point(100, 100), Point(600, 600), Scalar(255, 255, 0), 4, 8, 0);

    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

polylines()

        polylines()函数的原型有两个,如下:

函数参数 :

        img 图像

        pts 点数组

       isClosed 指示绘制的折线是否闭合。如果它们是闭合的,则该函数从每条曲线的最后一个顶                         点到其第一个顶点绘制一条线。

        thickness 线条厚度,缺省值为1

        lineType 线条类型, 缺省值为8

        shift 点坐标小数点位数

        示例程序

        在上面的示例函数中加入,画polines的代码,如下:

    //polines
    mpoints.clear();
    RNG rng1;
    for (int i = 0; i < 9; i++)
    {
        pt.x = rng1.uniform(300,1500);
        pt.y = rng1.uniform(800, 1000);
        mpoints.push_back(pt);
    }
    polylines(bgn, mpoints, 0, Scalar(0, 0, 255));

    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

试运行,结果如下:

putText()

        putText()函数的原型如下:

函数参数:

        img 图像

        text 要绘制的字符串

        org 图像中文本字符串的左下角。

        fontFace 字体类型,请参见HersheyFonts。下面是Hershey fonts类型

        fontScale 乘以字体特定基本大小的字体比例因子。

        color 绘制文本颜色

        thichness 线条厚度,缺省为1

        lineType 线条类型

        bottomLeftOrigin 如果为真,图像数据源位于左下角。否则,它位于左上角。

        示例程序

        在上面的示例程序中加入绘制字符串文本的代码, 如下:

       //polines
    mpoints.clear();
    RNG rng1;
    for (int i = 0; i < 9; i++)
    {
        pt.x = rng1.uniform(300,1500);
        pt.y = rng1.uniform(800, 1000);
        mpoints.push_back(pt);
    }
    polylines(bgn, mpoints, 0, Scalar(0, 0, 255));

    //putText
    putText(bgn, "Hello, OpenCV!, Hello World!", Point(500, 1000), FONT_ITALIC,1, Scalar(255,255,255), 4);

    imshow("Background", bgn);

    waitKey(0);

    return 0;
}

试运行,结果如下:

rectangle()

        rectangle()函数的原型有两个,如下:

函数参数:

        img 图像

        pt1 矩形的一个顶点

        pt2 矩形的另一个对角点

        rec 欲绘制的矩形

        color 绘制矩形颜色

        thickness 线条厚度,缺省为1

        lineType 线条类型,缺省为8

        shift 矩形顶点坐标的小数点位数,缺省为0

        示例程序

        在上面的示例程序中加入绘制矩形的代码,如下:

    //putText
    putText(bgn, "Hello, OpenCV!, Hello World!", Point(500, 1000), FONT_ITALIC,1, Scalar(255,255,255), 4);

    //retangle
    rectangle(bgn,Point(30, 850), Point(150, 1000), Scalar(255,255,255),4);
    rectangle(bgn, Rect(Point(60,880),Size(60,90)), Scalar(127, 127, 127), 4);

    imshow("Background", bgn);


    waitKey(0);

    return 0;
}

到这里,OpenCV常用绘图函数已介绍完毕。该博文的示例程序已上传到CSDN,若需仔细查看去下载到本地磁盘。其链接为:https://download.csdn.net/download/billliu66/89670302

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bill66

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值