opencv 画图

2020-12-20  本文已影响0人  此间不留白

learning opencv 第6章第1题解决方案

前言

opencv提供了丰富的函数用以图形绘制,包括矩形,线条,椭圆和多边形等,本篇文章对opencv的基本绘图函数做了一些介绍和说明。

椭圆绘制

绘制椭圆的函数说明和参数说明如下:

 void ellipse(InputOutputArray img, Point center, Size axes,
                        double angle, double startAngle, double endAngle,
                        const Scalar& color, int thickness = 1,
                        int lineType = LINE_8, int shift = 0);
@param InputOutputArray img  防止椭圆的图像
@param Point center 椭圆的中心
@param Szie axes 椭圆长短轴的尺寸
@param double angle 椭圆的角度(一个完整的椭圆应该有360度)
@param double startAngle 椭圆的的起始角度(第一象限按照逆时针开始计算)
@param double endAngle 椭圆的结束角度
@param const Scalar& color 椭圆的颜色(BGR表示)
@param int thickness 椭圆边框的粗细程度
@param int lineType 椭圆边框的连接类型,默认为8领域连接
@param int shift 中心坐标和轴的小数位数,一般是0

绘制一个椭圆的代码如下所示:

ellipse(img, Point(455,120),
                Size(126, 80), 360.0, 0.0, 360.0, Scalar(0, 0, 255), 1, 8, 0);

绘制单个多边形

opencv绘制多边形的函数说明如下,其基本参数与绘制椭圆的参数相似,需要注意的是,表述多边形顶点的参数,是一个Point 类型的数组

void fillConvexPoly(InputOutputArray img, const Point* pts, int npts,
                               const Scalar& color, int lineType = LINE_8,
                               int shift = 0);

绘制多个多边形

opencv 也提供了绘制多个多边形的函数,其说明如下,其基本参数与其他绘图函数的参数基本相同,不过,在表述多边形顶点的参数用到了二维数组和一维数组,如下:

void fillPoly(InputOutputArray img, const Point** pts,
                         const int* npts, int ncontours,
                         const Scalar& color, int lineType = LINE_8, int shift = 0,
                         Point offset = Point() );
@param const Point ** pts, 表示多个多边形顶点坐标的二维数组,如m个多边形,每个多边形有n个顶点
@param const int* npts, 多边形顶点数组成的一维数组
@param int ncontours,绘制多边形的个数
@param offset=Point(), 轮廓所有点可选偏移,一般保持默认即可 

绘制两个六边形的一个实例如下代码所示:

Point pt[2][6] = { {Point(100,100),Point(80,150),Point(100,200),
                Point(150,200),Point(170,150),Point(150,100)},
                {Point(300,300),Point(250,350),Point(300,400),Point(400,400),
                Point(450,350),Point(400,300)} };
int n[] = { 6,6 };
const Point* pp[] = { pt[0],pt[1] };
            
fillPoly(img, pp,n,2,Scalar(150, 186, 205), 8, 0);

以上代码绘制的多边形是填充后的多边形,opencv也提供了不带填充的多边形绘制函数,如下所示:

 void polylines(InputOutputArray img, const Point* const* pts, const int* npts,
                          int ncontours, bool isClosed, const Scalar& color,
                          int thickness = 1, int lineType = LINE_8, int shift = 0 );

绘制线段

opencv提供了绘制线段的函数,其实现比较简单,由两个起点坐标和终点坐标两个参数决定:

void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
                     int thickness = 1, int lineType = LINE_8, int shift = 0);

总结

综上,回顾了opencv中几个基本的绘图函数,由以上几个示例,完成的一个opencv绘图的基本示例如下代码所示:

首先,未绘制任何图像的图像如下图所示:


总体实现代码如下:

#include<iostream>
#include<opencv2/opencv.hpp>
/* (1) Load or create and display a color image
*  (2) Draw one example of every shape and line that opencv can draw
*
*/
using namespace cv;
int main()
{
    Mat img = imread("daminggong.PNG");
    int s = 0;
    int width = img.rows;
    int height = img.cols;
    std::cout << "\r\t在图像上绘制图形" << std::endl;
    std::cout << "\r\t输入0,绘制椭圆" << std::endl;
    std::cout << "\r\t输入1,绘制多边形" << std::endl;
    std::cout << "\r\t输入2,绘制多个填充多边形" << std::endl;
    std::cout << "\r\t输入3,绘制线段" << std::endl;
    std::cout << "\r\t输入4,绘制无填充多边形" << std::endl;
    std::cout << "\r\t输入99,结束绘制" << std::endl;
    while (std::cin >> s)
    { 
        // 画个椭圆
        if (s == 0)
        {
            ellipse(img, Point(455,120),
                Size(126, 80), 360.0, 0.0, 360.0, Scalar(0, 0, 255), 1, 8, 0);
        }
        //绘制多边形
        else if (s == 1)
        {
            //多个顶点的坐标
            Point PointArray[4] = {Point(50,50),Point(50,100),Point(100,100),Point(100,50) };
            
            fillConvexPoly(img,PointArray,4,Scalar(34,180,238),8,0);
        }//绘制两个多边形
        else if (s == 2)
        {
            Point pt[2][6] = { {Point(100,100),Point(80,150),Point(100,200),
                Point(150,200),Point(170,150),Point(150,100)},
                {Point(300,300),Point(250,350),Point(300,400),Point(400,400),
                Point(450,350),Point(400,300)} };
            int n[] = { 6,6 };
            const Point* pp[] = { pt[0],pt[1] };
            
            fillPoly(img, pp,n,2,Scalar(150, 186, 205), 8, 0);
        }
        //绘制线
        else if (s == 3)
        {
            line(img, Point(720,100), Point(720, 400), Scalar(255, 255, 0),2, 8, 0);
        }
        else if (s == 4)
        {
            Point pt_line[1][5] = { {Point(650,250),Point(600,300),Point(630,350),
                Point(680,350),Point(700,300)} };
                
            int count[] = {5};
            const Point *p_line[] = {pt_line[0]};
            polylines(img, p_line,count,1,1,Scalar(0, 255, 160), 2, 8, 0);
        }
        else if(s==99)
        {
            break;
        }
        else
        {
            std::cerr << "输入错误,请输入0-4之间的整数" << std::endl;
            continue;
        }
    }
    imshow("img_ed", img);
    imwrite("img_ed.PNG", img);
    waitKey(0);
    return 0;
}

实现所有代码后,其效果如下:


上一篇下一篇

猜你喜欢

热点阅读