OpenCV-C++ 绘制基本形状与编写文字

这一小节首先介绍一下PointScalar两个类的使用,以及介绍如何在图像上绘制一些几何形状和添加文字, 具体包括: 线, 矩形, 圆, 椭圆, 多边形等

完整的代码在最下方;

Point与Scalar

Point

Point表示的是二维平面上的一个点,包含两个属性\(x, y\);

使用方式如下:

// 构建一个点
Point pt = Point(10, 20);

// 或者
Point pt;
pt.x = 10;
pt.y = 20;

Scalar

Scalar表示的是一个向量, 其本质是一个由长度为4的数组作为元素的结构体;

typedef struct Scalar{
    double val[4];
}Scalar;

使用场景在下面绘制几何图形时会用到;

绘制几何图形

绘制几何图形包括线, 矩形, 椭圆, 圆,多边形

画线

关于line的API如下:

void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
          int thickness = 1, int lineType = LINE_8, int shift = 0);
  • img表示需要绘制线的图像;
  • pt1pt2表示线段的两端;
  • color表示线的颜色,以Scalar进行定义;
  • thickness表示线的粗细;
  • lineType表示线的类型;

在图像上绘制一条线, API的使用:

// 画线方法
void MyLine(Mat src){

    Point p1 = Point(10, 20);
    Point p2;
    p2.x = 300;
    p2.y = 300;

    Scalar color = Scalar(0, 0, 255);
    //画线
    line(src, p1, p2, color, 2, LINE_8);
}
  • 首先创建线段两个端点的位置,利用Point;
  • 其次利用Scalar创建一个颜色;

绘制矩形

关于rectangle的API介绍如下:

void rectangle(InputOutputArray img, Rect rec,
               const Scalar& color, int thickness = 1,
               int lineType = LINE_8, int shift = 0);
  • img输入图像
  • rec表示一个矩形类,下面介绍
  • color, thickness, lineType, shift含义与上述相同;

关于Rect的API介绍如下:

class Rect_{
    public:
		Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
}

  • 其中_x, _y分别表示矩形的左上角坐标, _width, _height表示矩形的宽度和高度;

举例, 在一张图像上绘制矩形:

// 绘制矩形方法
void MyRectangle(Mat src){
    Rect rect = Rect(200, 100, 300, 300);
    Scalar color = Scalar(0, 0, 255);

    // 绘制矩形
    rectangle(src, rect, color, 2, LINE_8);
}
  • 首先,构建矩形rect;
  • 其次绘图;

绘制椭圆

有关ellipse绘制椭圆的API介绍如下:

void ellipse(InputOutputArray img, Point center, Size axes,
             double angle, double startAngle, double endAngle,
             const Scalar& color, int thickness = 1,
             nt lineType = LINE_8, int shift = 0);
  • img为输入图像;
  • center表示椭圆中心;
  • axes分别表示椭圆横,纵向长度;
  • angle表示顺时针旋转多少度;
  • startAngleendAngle配合使用,表示从左上角逆时针,绘制多少度的椭圆;
  • 后面参数与前述相同;

举例,在一张图像上绘制椭圆:


// 绘制椭圆
void MyEllipse(Mat src){
    Point center = Point(src.rows/2, src.cols/2);
    Size size = Size(src.cols/4, src.rows/8);
    Scalar color = Scalar(0, 0, 255);
    ellipse(src, center, size, 30, 0, 360, color, LINE_8);
}
  • 构造中心点
  • 椭圆横,纵长度
  • 颜色

绘制圆

有关circle的API的介绍如下:

void circle(InputOutputArray img, Point center, int radius,
            const Scalar& color, int thickness = 1,
            int lineType = LINE_8, int shift = 0);
  • img表示需要绘制的图像;
  • center表示中心点坐标;
  • radius表示半径大小;
  • 其他如前述一致;

举例,在图像上绘制一个圆:

// 绘制圆
void MyCircle(Mat src){
    Scalar color = Scalar(0, 0, 255);
    Point center = Point(src.rows/4, src.cols/2);
    int radius = 100;

    // 绘制圆
    circle(src, center, radius, color, 2, LINE_8);
}

绘制多边形

有关绘制多边形fillPolyAPI的使用介绍如下:

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() );
  • img多边形将要绘制到该图像上;
  • pts表示多边形的顶点集
  • npts表示顶点数目;
  • ncontours表示要绘制的多边形数量
  • 其他与前述一致

举例,在图像中绘制一个多边形,如下:

// 绘制多边形
void MyPolygon(Mat src){

    Point pts[1][5];
    pts[0][0] = Point(100, 100);
    pts[0][1] = Point(100, 200);
    pts[0][2] = Point(200, 200);
    pts[0][3] = Point(200, 100);
    pts[0][4] = Point(100, 100);
    const Point* ppts[] = {pts[0]};
    int npt[] = {5};

    Scalar color = Scalar(255, 0, 255);

    // 绘制多边形
    fillPoly(src, ppts, npt, 1, color, LINE_8);
}
  • pts顶点集,ppts指针

随机画线

举例,在一张图像上随机画出一些线段;

// 随机画线
void RandomLineDemo(Mat src){
    // 新的图像
    Mat dst = Mat::zeros(src.size(), src.type());

    RNG rng(12345);
    Point pt1;
    Point pt2;

    namedWindow("dst", WINDOW_AUTOSIZE);
    for (int i = 0; i < 10000000; i++){
        pt1.x = rng.uniform(0, src.cols);
        pt2.x = rng.uniform(0, src.cols);
        pt1.y = rng.uniform(0, src.rows);
        pt2.y = rng.uniform(0, src.rows);

        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));  // 随机产生颜色
        // 停止条件
        if (waitKey(50) > 0) {
            break;
        }

        line(dst, pt1, pt2, color, 1, LINE_8);
        imshow("dst", dst);
    }
}

添加文字

在图像中添加文字,putText方法的使用介绍如下:

void putText( InputOutputArray img, const String& text, Point org,
             int fontFace, double fontScale, Scalar color,
             int thickness = 1, int lineType = LINE_8,
             bool bottomLeftOrigin = false );
  • img表示将要添加文字的图像;
  • text表示需要添加的文本
  • org表示文件左下角坐标位置;
  • fontFace表示字体类型
  • fontScale表示问题缩放尺度,有一个默认的大小;
  • color表示图像颜色,其他如前述一致;

举例,在一张图像中绘制一段文字;

putText(src, 
        "Hello OpenCV",
        Point(100, 100),
        FONT_HERSHEY_COMPLEX,
        0.8, 
        Scalar(0, 255, 255), 2, LINE_8);

完整代码如下:

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

using namespace std;
using namespace cv;

void MyLine(Mat src);  // 画线方法
void MyRectangle(Mat src);  // 绘制矩形方法
void MyEllipse(Mat src);  // 绘制椭圆
void MyCircle(Mat src);  // 绘制圆
void MyPolygon(Mat src);  // 绘制多边形

void RandomLineDemo(Mat src);  // 随机画线


int main(){

    // 读取图像
    Mat src = imread("/home/chen/dataset/lena.jpg");
    if (src.empty()){
        printf("could not load image.\n");
        return -1;
    }

    // 在图像上画线
    MyLine(src);

    // 在图像上画矩形
    MyRectangle(src);

    // 在凸显上绘制椭圆
    MyEllipse(src);

    // 绘制圆
    MyCircle(src);

    // 绘制多边形
    MyPolygon(src);

    // 写入文字
    // 字体左下端的坐标
    putText(src, "Hello OpenCV", Point(100, 100), FONT_HERSHEY_COMPLEX, 0.8, Scalar(0, 255, 255), 2, LINE_8);

    // 随机画线
    RandomLineDemo(src);

    namedWindow("src", WINDOW_AUTOSIZE);
    imshow("src", src);  
    waitKey(0);


    return 0; 
}

// 画线方法
void MyLine(Mat src){

    Point p1 = Point(10, 20);
    Point p2;
    p2.x = 300;
    p2.y = 300;

    Scalar color = Scalar(0, 0, 255);
    //画线
    line(src, p1, p2, color, 2, LINE_8);
}

// 绘制矩形方法
void MyRectangle(Mat src){
    Rect rect = Rect(200, 100, 300, 300);
    Scalar color = Scalar(0, 0, 255);

    // 绘制矩形
    rectangle(src, rect, color, 2, LINE_8);
}

// 绘制椭圆
void MyEllipse(Mat src){
    Point center = Point(src.rows/2, src.cols/2);
    Size size = Size(src.cols/4, src.rows/8);
    Scalar color = Scalar(0, 0, 255);
    
    // 绘制椭圆
    // 第一个参数表示绘图
    // 第二个参数表示椭圆中心
    // 第三个参数分别表示横轴, 纵轴长度,用Size类型表示
    // 第四个参数表示顺时针倾斜角度
    // 第五,六个参数表示从左上角逆时针开始绘制,绘制多少角度
    ellipse(src, center, size, 30, 0, 360, color, LINE_8);
}

// 绘制圆
void MyCircle(Mat src){
    Scalar color = Scalar(0, 0, 255);
    Point center = Point(src.rows/4, src.cols/2);
    int radius = 100;

    // 绘制圆
    circle(src, center, radius, color, 2, LINE_8);
}

// 绘制多边形
void MyPolygon(Mat src){

    Point pts[1][5];
    pts[0][0] = Point(100, 100);
    pts[0][1] = Point(100, 200);
    pts[0][2] = Point(200, 200);
    pts[0][3] = Point(200, 100);
    pts[0][4] = Point(100, 100);
    const Point* ppts[] = {pts[0]};
    int npt[] = {5};

    Scalar color = Scalar(255, 0, 255);

    // 绘制多边形
    fillPoly(src, ppts, npt, 1, color, LINE_8);
}

// 随机画线
void RandomLineDemo(Mat src){
    // 新的图像
    Mat dst = Mat::zeros(src.size(), src.type());

    RNG rng(12345);
    Point pt1;
    Point pt2;

    namedWindow("dst", WINDOW_AUTOSIZE);
    for (int i = 0; i < 10000000; i++){
        pt1.x = rng.uniform(0, src.cols);
        pt2.x = rng.uniform(0, src.cols);

        pt1.y = rng.uniform(0, src.rows);
        pt2.y = rng.uniform(0, src.rows);

        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));  // 随机产生颜色
        // 停止条件
        if (waitKey(50) > 0) {
            break;
        }

        line(dst, pt1, pt2, color, 1, LINE_8);
        imshow("dst", dst);

    }
}

posted @ 2021-04-06 12:05  chenzhen0530  阅读(2397)  评论(0编辑  收藏  举报