OpenCvOpenCV

opencv基本画图

2017-09-27  本文已影响96人  寻找时光机

目标

在本教程中,将学习如何:

OpenCV理论

对于本教程,大量使用两个结构:cv :: Pointcv :: Scalar

point

2D point, 由图像 x, y坐标确定,可以定义成:

Point pt;
pt.x = 10;
pt.y = 8;

Point pt = Point(10, 8);

Scalar

Scalar(a, b, c)

将定义一个BGR颜色,例如:Blue = aGreen = bRed = c.

代码实现

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

#define w 400
using namespace cv;

void MyEllipse(Mat img, double angle);

void MyFilledCircle(Mat img, Point center);

void MyPolygon(Mat img);

void MyLine(Mat img, Point start, Point end);

int main(void) 
{
    char atom_window[] = "Drawing 1: Atom";
    char rook_window[] = "Drawing 2: Rook";

    Mat atom_image = Mat::zeros(w, w, CV_8UC3);
    Mat rook_image = Mat::zeros(w, w, CV_8UC3);

    MyEllipse(atom_image, 90);
    MyEllipse(atom_image, 0);
    MyEllipse(atom_image, 45);
    MyEllipse(atom_image, -45);

    MyFilledCircle(atom_image, Point(w / 2, w / 2));

    MyPolygon(rook_image);

    rectangle(rook_image,
        Point(0, 7 * w / 8),
        Point(w, w),
        Scalar(0, 255, 255),
        FILLED,
        LINE_8);

    MyLine(rook_image, Point(0, 15 * w / 16), Point(w, 15 * w / 16));
    MyLine(rook_image, Point(w / 4, 7 * w / 8), Point(w / 4, w));
    MyLine(rook_image, Point(w / 2, 7 * w / 8), Point(w / 2, w));
    MyLine(rook_image, Point(3 * w / 4, 7 * w / 8), Point(3 * w / 4, w));

    imshow(atom_window, atom_image);
    moveWindow(atom_window, 0, 200);

    imshow(rook_window, rook_image);
    moveWindow(rook_window, w, 200);

    waitKey(0);
    return(0);
}
void MyEllipse(Mat img, double angle)
{
    int thickness = 2;
    int lineType = 8;
    ellipse(img,
        Point(w / 2, w / 2),
        Size(w / 4, w / 16),
        angle,
        0,
        360,
        Scalar(255, 0, 0),
        thickness,
        lineType);
}
void MyFilledCircle(Mat img, Point center)
{
    circle(img,
        center,
        w / 32,
        Scalar(0, 0, 255),
        FILLED,
        LINE_8);
}
void MyPolygon(Mat img)
{
    int lineType = LINE_8;
    Point rook_points[1][20];
    rook_points[0][0] = Point(w / 4, 7 * w / 8);
    rook_points[0][1] = Point(3 * w / 4, 7 * w / 8);
    rook_points[0][2] = Point(3 * w / 4, 13 * w / 16);
    rook_points[0][3] = Point(11 * w / 16, 13 * w / 16);
    rook_points[0][4] = Point(19 * w / 32, 3 * w / 8);
    rook_points[0][5] = Point(3 * w / 4, 3 * w / 8);
    rook_points[0][6] = Point(3 * w / 4, w / 8);
    rook_points[0][7] = Point(26 * w / 40, w / 8);
    rook_points[0][8] = Point(26 * w / 40, w / 4);
    rook_points[0][9] = Point(22 * w / 40, w / 4);
    rook_points[0][10] = Point(22 * w / 40, w / 8);
    rook_points[0][11] = Point(18 * w / 40, w / 8);
    rook_points[0][12] = Point(18 * w / 40, w / 4);
    rook_points[0][13] = Point(14 * w / 40, w / 4);
    rook_points[0][14] = Point(14 * w / 40, w / 8);
    rook_points[0][15] = Point(w / 4, w / 8);
    rook_points[0][16] = Point(w / 4, 3 * w / 8);
    rook_points[0][17] = Point(13 * w / 32, 3 * w / 8);
    rook_points[0][18] = Point(5 * w / 16, 13 * w / 16);
    rook_points[0][19] = Point(w / 4, 13 * w / 16);
    const Point* ppt[1] = { rook_points[0] };
    int npt[] = { 20 };
    fillPoly(img,
        ppt,
        npt,
        1,
        Scalar(255, 255, 255),
        lineType);
}
void MyLine(Mat img, Point start, Point end)
{
    int thickness = 2;
    int lineType = LINE_8;
    line(img,
        start,
        end,
        Scalar(0, 0, 0),
        thickness,
        lineType);
}

解释

绘制两个例子(一个原子和一个车),我们必须创建两个图像和两个窗口来显示它们。

char atom_window[] = "Drawing 1: Atom";
char rook_window[] = "Drawing 2: Rook";
Mat atom_image = Mat::zeros(w, w, CV_8UC3);
Mat rook_image = Mat::zeros(w, w, CV_8UC3);

我们创建了绘制不同几何形状的功能。例如,为了绘制原子,我们使用MyEllipse和MyFilledCircle:

MyEllipse(atom_image, 90);
MyEllipse(atom_image, 0);
MyEllipse(atom_image, 45);
MyEllipse(atom_image, -45);
MyFilledCircle(atom_image, Point(w / 2, w / 2));

并提请我们所使用的车MYLINE,矩形和MyPolygon:

MyPolygon(rook_image);
rectangle(rook_image,
    Point(0, 7 * w / 8),
    Point(w, w),
    Scalar(0, 255, 255),
    FILLED,
    LINE_8);
MyLine(rook_image, Point(0, 15 * w / 16), Point(w, 15 * w / 16));
MyLine(rook_image, Point(w / 4, 7 * w / 8), Point(w / 4, w));
MyLine(rook_image, Point(w / 2, 7 * w / 8), Point(w / 2, w));
MyLine(rook_image, Point(3 * w / 4, 7 * w / 8), Point(3 * w / 4, w));

MyLine

void MyLine(Mat img, Point start, Point end)
{
    int thickness = 2;
    int lineType = LINE_8;
    line(img,
        start,
        end,
        Scalar(0, 0, 0),
        thickness,
        lineType);
}

我们可以看到,MyLine只是调用函数line(),它执行以下操作:

MyEllipse

void MyEllipse(Mat img, double angle)
{
    int thickness = 2;
    int lineType = 8;
    ellipse(img,
        Point(w / 2, w / 2),
        Size(w / 4, w / 16),
        angle,
        0,
        360,
        Scalar(255, 0, 0),
        thickness,
        lineType);
}

从上面的代码,我们可以看到函数ellipse()绘制一个椭圆,使得:

MyFilledCircle

void MyFilledCircle(Mat img, Point center)
{
    circle(img,
        center,
        w / 32,
        Scalar(0, 0, 255),
        FILLED,
        LINE_8);
}

类似于椭圆函数,我们可以观察到圆接受作为参数:

MyPolygon

void MyPolygon(Mat img)
{
    int lineType = LINE_8;
    Point rook_points[1][20];
    rook_points[0][0] = Point(w / 4, 7 * w / 8);
    rook_points[0][1] = Point(3 * w / 4, 7 * w / 8);
    rook_points[0][2] = Point(3 * w / 4, 13 * w / 16);
    rook_points[0][3] = Point(11 * w / 16, 13 * w / 16);
    rook_points[0][4] = Point(19 * w / 32, 3 * w / 8);
    rook_points[0][5] = Point(3 * w / 4, 3 * w / 8);
    rook_points[0][6] = Point(3 * w / 4, w / 8);
    rook_points[0][7] = Point(26 * w / 40, w / 8);
    rook_points[0][8] = Point(26 * w / 40, w / 4);
    rook_points[0][9] = Point(22 * w / 40, w / 4);
    rook_points[0][10] = Point(22 * w / 40, w / 8);
    rook_points[0][11] = Point(18 * w / 40, w / 8);
    rook_points[0][12] = Point(18 * w / 40, w / 4);
    rook_points[0][13] = Point(14 * w / 40, w / 4);
    rook_points[0][14] = Point(14 * w / 40, w / 8);
    rook_points[0][15] = Point(w / 4, w / 8);
    rook_points[0][16] = Point(w / 4, 3 * w / 8);
    rook_points[0][17] = Point(13 * w / 32, 3 * w / 8);
    rook_points[0][18] = Point(5 * w / 16, 13 * w / 16);
    rook_points[0][19] = Point(w / 4, 13 * w / 16);
    const Point* ppt[1] = { rook_points[0] };
    int npt[] = { 20 };
    fillPoly(img,
        ppt,
        npt,
        1,
        Scalar(255, 255, 255),
        lineType);
}

要绘制一个填充的多边形,我们使用函数fillPoly()。我们注意到:

结果

上一篇 下一篇

猜你喜欢

热点阅读