"Mid-Autumn Festival is coming" I didn't expect that I could draw such a beautiful mooncake using OpenCV "Source code attached"

I. Introduction

The Mid-Autumn Festival is coming soon. As one of the traditional Chinese festivals, in addition to tasting delicious mooncakes and admiring the moon, people also like to express their joy and blessings for this festival through paintings. Nowadays, with the continuous development of technology, it is really eye-opening that you can use the computer vision library OpenCV to draw exquisite mooncakes and cute jade rabbit images.

OpenCV, full name Open Source Computer Vision Library, is an open source library widely used in the field of computer vision. It provides many powerful image processing and computer vision functions, providing developers with rich tools and functions, making it relatively easy to implement various image operations. Its flexibility and efficiency are favored by the majority of developers.

At a special moment like the Mid-Autumn Festival, using OpenCV to draw images of moon cakes and jade rabbits can not only show respect and support for traditional culture, but also combine the power of modern technology to create unique and exquisite works. Through OpenCV, you can draw mooncakes with a strong festive atmosphere. Whether it is its smooth appearance or uneven texture, it can be vividly displayed in front of you. At the same time, using OpenCV to draw the image of the jade rabbit can show a cute cartoon style, combining traditional elements with fashion trends, giving people a refreshing feeling.

In addition to drawing moon cakes and jade rabbits, OpenCV also provides a wealth of drawing functions, such as drawing basic geometric shapes, lines and text, providing a wide range of creative space. By calling these functions, you can easily realize various drawing needs and add unique visual effects to your works.

When using OpenCV, you first need to install the corresponding library files and become familiar with their usage. By learning the basic operations and function calls of OpenCV, you can better utilize this powerful tool to realize your own ideas. Whether you are a professional computer vision developer or a beginner interested in image processing, mastering OpenCV is a good choice.

This Mid-Autumn Festival, you might as well try using OpenCV to draw exquisite mooncakes and cute jade rabbit images, and feel the collision of traditional culture and modern technology. Use a paintbrush to paint on the computer screen, freeze this beautiful moment, and welcome the Mid-Autumn Festival together with the power of OpenCV.

This is the ideal rendering of a loading image display.
image-20230913175620586

image-20230913175512032

2. Draw sample display

image-20230913175222845

image-20230913175457441

image-20230913175725373

image-20230913175752185

3. OpenCV installation

3.1 OpenCV download

OpenCV download address: https://opencv.org/releases/page/3/

The latest version is 4.3, so download the latest version.

image-20230906101920240

image-20230906102004369

The download is an exe file, which can be installed by double-clicking it. It is actually decompressed. You can choose the decompression path. The decompressed file contains a lot of source files and library files. It is relatively large and can be placed directly in a fixed directory. The following procedures Just fill in the path directly to call it. This downloaded library file only contains the X64 library, which is suitable for the MSVS 64-bit compiler.

image-20230906102712398

Decompression is complete.

image-20230906103311462

After decompression, you will see directories for VC14 and VC15 in the build directory. What does this mean?

The difference between OpenCV VC14 and VC15 is the compiler version they use. VC14 uses the Visual Studio 2015 compiler, while VC15 uses the Visual Studio 2017 compiler. This means that VC15 can take advantage of more advanced compiler technology, thereby improving the performance and efficiency of your code. In addition, VC15 also supports more C++11 and C++14 features, making development more convenient and flexible.

image-20230906103633870

3.2 VS2022 environment

Here I will introduce the installation process of the environment I use. All versions of VS are available. OpenCV is just a third-party library and can be called anywhere.

My current environment is under Windows, and the IDE I use is the strongest IDEVS2022 on the surface.

Download address: https://visualstudio.microsoft.com/zh-hans/downloads/

image-20230913173131481

Because I only need to use C++ and C language programming here, you can choose the packages you need to install when installing.

image-20230913173258088

After installation, create the project.

image-20230913173330580

image-20230913173349914

3.3 New construction

This is an empty project that I created. I wrote a piece of OpenCV code.

image-20230913173536785

After the project is created, you need to add a reference to the OpenCV header file and a reference to the OpenCV library file.

Click on this property.

image-20230913173632169

The first step is to add the used OpenCV header file path in C++ and general options.

image-20230913173709390

Where exactly this path is depends on your OpenCV installation path.

image-20230913173753881

For the convenience of everyone, I post it here.

C:/opencv_4.x/opencv/build/include/opencv2
C:/opencv_4.x/opencv/build/include/opencv
C:/opencv_4.x/opencv/build/include

The second step is to set the path to the library file. In Linker-Input Options, add dependency options.

image-20230913173957033

Where is this library? Fill it in based on your OpenCV decompression path.

image-20230913174030657

This is my path:

C:/opencv_4.x/opencv/build/x64/vc15/lib/opencv_world430.lib

3.4 Copy of runtime library

If you have written the OpenCV code, just press to Ctrl + F5run the program. If you run it for the first time, an error will be reported.

The tips are as follows:

image-20230913174225139

This prompt tells us that the OpenCV runtime library cannot be found when the program is running. As long as you use a third-party library, you need to know this. When running, you need to copy the library used to the same level directory of the generated exe.

Copy the files in the OpenCV decompression directory opencv_world430.dllto the directory at the same level as the compiled exe. Otherwise, the program will end abnormally because the library cannot be found.

image-20230912102245746

Copy it here.

image-20230913174403148

Run it again and the program will run normally.

image-20230913175414887

4. Introduction to OpenCV drawing functions

OpenCV provides a series of functions for image processing and drawing, including some commonly used drawing functions. The following are some of the commonly used drawing functions:

4.1 cv::line: Draw a straight line

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

Parameter Description:

  • img: The image to draw a straight line.
  • pt1: The starting point coordinates of the straight line.
  • pt2: The coordinates of the end point of the straight line.
  • color: The color of the line.
  • thickness: Line width of the straight line, default is 1.
  • lineType: The type of straight line, the default is 8-connected line ( cv::LINE_8).
  • shift: The number of decimal places for coordinates, default is 0.

4.2 cv::rectangle: Draw a rectangle

void cv::rectangle(cv::Mat& img, cv::Rect rect, const cv::Scalar& color,
                   int thickness=1, int lineType=cv::LINE_8,
                   int shift=0);

Parameter Description:

  • img: The image of the rectangle to be drawn.
  • rect: The size and position information of the rectangle, that is, the coordinates of the upper left corner, width and height.
  • color:The color of the rectangle.
  • thickness: Line width of the rectangle, default is 1.
  • lineType: The type of rectangle, the default is 8-connected line ( cv::LINE_8).
  • shift: The number of decimal places for coordinates, default is 0.

4.3 cv::circle: Draw a circle

void cv::circle(cv::Mat& img, cv::Point center, int radius,
                const cv::Scalar& color, int thickness=1,
                int lineType=cv::LINE_8, int shift=0);

Parameter Description:

  • img: To draw a circular image.
  • center: The coordinates of the center of the circle.
  • radius: The radius of the circle.
  • color: The color of the circle.
  • thickness: The line width of the circle, default is 1.
  • lineType: The type of circle, the default is 8-connected line ( cv::LINE_8).
  • shift: The number of decimal places for coordinates, default is 0.

4.4 cv::ellipse: Draw an ellipse

void cv::ellipse(cv::Mat& img, cv::Point center,
                 cv::Size axes, double angle, double startAngle,
                 double endAngle, const cv::Scalar& color,
                 int thickness=1, int lineType=cv::LINE_8,
                 int shift=0);

Parameter Description:

  • img: To draw an elliptical image.
  • center: The coordinates of the ellipse center.
  • axes: The size of the major and minor axes of the ellipse.
  • angle: The rotation angle of the ellipse, in degrees.
  • startAngle: The starting angle of the ellipse, in degrees.
  • endAngle: The ending angle of the ellipse, in degrees.
  • color:The color of the ellipse.
  • thickness: The line width of the ellipse, the default is 1.
  • lineType: The type of ellipse, the default is 8-connected line ( cv::LINE_8).
  • shift: The number of decimal places for coordinates, default is 0.

4.5 cv::putText: Draw text in image

void cv::putText(cv::Mat& img, const std::string& text,
                 cv::Point org, int fontFace, double fontScale,
                 const cv::Scalar& color, int thickness=1,
                 int lineType=cv::LINE_8, bool bottomLeftOrigin=false);

Parameter Description:

  • img: The image on which to draw the text.
  • text: The text content to be drawn.
  • org: The coordinates of the lower left corner of the text.
  • fontFace: Type of font.
  • fontScale: The scaling ratio of the font.
  • color: The color of the font.
  • thickness: The line width of the font, the default is 1.
  • lineType: Font type, the default is 8 connected lines ( cv::LINE_8).
  • bottomLeftOrigin: Whether to take the lower left corner as the origin, the default is false, that is, the upper left corner is the origin.

4.6 cv::polylines: Draw the boundaries of polygons.

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

Parameter Description:

  • img: The image of the polygon to be drawn.
  • pts: Coordinate array of each vertex of the polygon.
  • npts: Array of the number of vertices of each closed loop of the polygon.
  • ncontours: The number of polygons.
  • isClosed: Whether to close the polygon.
  • color: The color of the polygon.
  • thickness: Line width of polygon boundary, default is 1.
  • lineType: The type of polygon, the default is 8-connected line ( cv::LINE_8).
  • shift: The number of decimal places for coordinates, default is 0.

4.7 cv::fillPoly: Fill inside the polygon.

void cv::fillPoly(cv::Mat& img, const cv::Point** pts,
                  const int* npts, int ncontours,
                  const cv::Scalar& color,
                  int lineType=cv::LINE_8, int shift=0,
                  cv::Point offset=cv::Point());

Parameter Description:

  • img: The image to fill the polygon with.
  • pts: Pointer to the coordinate array of each vertex of the polygon.
  • npts: Array of the number of vertices of each closed loop of the polygon.
  • ncontours: The number of polygons.
  • color: Fill color.
  • lineType: The type of polygon, the default is 8-connected line ( cv::LINE_8).
  • shift: The number of decimal places for coordinates, default is 0.
  • offset: Offset when filling polygons.

4.8 Examples of using cv::polylines and cv::fillPoly

cv::Mat image(500, 500, CV_8UC3, cv::Scalar(255, 255, 255));  // 创建一张白色图像

// 定义多边形的顶点坐标
cv::Point pts[1][4];
pts[0][0] = cv::Point(100, 100);
pts[0][1] = cv::Point(200, 100);
pts[0][2] = cv::Point(200, 200);
pts[0][3] = cv::Point(100, 200);

// 绘制多边形的边界
const cv::Point* ppt[1] = {
    
     pts[0] };
int npt[] = {
    
     4 };
cv::polylines(image, ppt, npt, 1, true, cv::Scalar(0, 0, 255), 2);

// 填充多边形的内部
cv::fillPoly(image, ppt, npt, 1, cv::Scalar(0, 255, 0));

// 显示图像
cv::imshow("Image", image);
cv::waitKey(0);

This example code creates a white image and draws a rectangle with a red border on the image, while filling the interior of the rectangle with green. By using cv::polylinesthe and cv::fillPolyfunctions, you can draw more complex polygonal shapes and fill effects.

5. Mooncake and Jade Rabbit drawing codes

5.1 The simplest mooncake

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个黑色背景图像作为画布
    cv::Mat canvas(400, 400, CV_8UC3, cv::Scalar(0, 0, 0));

    // 定义月饼的参数
    cv::Point center(canvas.cols / 2, canvas.rows / 2);
    int radius = 150;
    cv::Scalar mooncakeColor(139, 69, 19); // 棕色

    // 绘制月饼的主体
    cv::circle(canvas, center, radius, mooncakeColor, cv::FILLED);

    // 在窗口中显示绘制的月饼
    cv::imshow("Circular Mooncake", canvas);
    cv::waitKey(0);

    return 0;
}

The code creates a black background image with a size of 400x400 pixels, and uses cv::circle()the function to draw a round brown mooncake. Draw a circular mooncake by specifying the center coordinates, radius and color. Finally, the drawn mooncake is displayed in the window.

5.2 The simplest Jade Rabbit

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个黑色背景图像作为画布
    cv::Mat canvas(400, 400, CV_8UC3, cv::Scalar(0, 0, 0));

    // 绘制兔子身体
    cv::ellipse(canvas, cv::Point(canvas.cols / 2, canvas.rows / 2), cv::Size(150, 200), 0, 0, 360, cv::Scalar(255, 255, 255), cv::FILLED);

    // 绘制兔子内耳朵
    cv::ellipse(canvas, cv::Point(canvas.cols / 2 - 60, canvas.rows / 2 - 110), cv::Size(70, 100), 0, 0, 360, cv::Scalar(255, 255, 255), cv::FILLED);
    cv::ellipse(canvas, cv::Point(canvas.cols / 2 + 60, canvas.rows / 2 - 110), cv::Size(70, 100), 0, 0, 360, cv::Scalar(255, 255, 255), cv::FILLED);

    // 绘制兔子眼睛
    cv::circle(canvas, cv::Point(canvas.cols / 2 - 40, canvas.rows / 2), 20, cv::Scalar(0, 0, 0), cv::FILLED);
    cv::circle(canvas, cv::Point(canvas.cols / 2 + 40, canvas.rows / 2), 20, cv::Scalar(0, 0, 0), cv::FILLED);

    // 绘制兔子嘴巴
    cv::ellipse(canvas, cv::Point(canvas.cols / 2, canvas.rows / 2 + 60), cv::Size(60, 30), 0, 180, 360, cv::Scalar(0, 0, 0), cv::FILLED);

    // 绘制兔子鼻子
    cv::circle(canvas, cv::Point(canvas.cols / 2, canvas.rows / 2 + 40), 10, cv::Scalar(255, 0, 0), cv::FILLED);

    // 在窗口中显示绘制的兔子
    cv::imshow("Rabbit", canvas);
    cv::waitKey(0);

    return 0;
}

Code l creates a black background image with a size of 400x400 pixels, and uses the cv::ellipse()and cv::circle()functions to draw the rabbit's body, inner ears, eyes, mouth and nose. Draw different parts by specifying parameters such as center point, size, angle, and color. Finally, the drawn bunny is displayed in the window.

5.3 Draw mooncakes with patterned outlines

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个画布,大小为800x800像素
    cv::Mat canvas(800, 800, CV_8UC3, cv::Scalar(255, 255, 255));

    // 设置画笔属性
    int thickness = 20;
    cv::Scalar color(245, 225, 111); // 黄色
    int lineType = cv::LINE_8;

    // 绘制太阳花花瓣
    for (int i = 0; i < 20; ++i)
    {
    
    
        // 计算当前花瓣的角度
        double angle = i * 18.0;

        // 计算当前花瓣的终点坐标
        double x = 400 + 220 * cos(angle * CV_PI / 180);
        double y = 400 + 220 * sin(angle * CV_PI / 180);

        // 绘制直线
        cv::line(canvas, cv::Point(400, 400), cv::Point(x, y), color, thickness, lineType);

        // 绘制半圆
        cv::Point center(x, y);
        cv::ellipse(canvas, center, cv::Size(40, 40), 0, 180, 360, color, -1);
    }

    // 绘制中心圆
    cv::Scalar fill_color(255, 153, 51); // 橙色
    cv::Point center(400, 400);
    cv::circle(canvas, center, 200, fill_color, -1);

    // 绘制花瓣图案
    cv::Scalar petal_color(245, 225, 111); // 黄色
    for (int i = 0; i < 12; ++i)
    {
    
    
        // 计算当前花瓣的起点和终点角度
        double startAngle = i * 30.0;
        double endAngle = startAngle + 120.0;

        // 绘制圆弧
        cv::ellipse(canvas, center, cv::Size(60, 60), 0, startAngle, endAngle, petal_color, -1);

        // 旋转180度,绘制对称的圆弧
        cv::ellipse(canvas, center, cv::Size(60, 60), 0, startAngle + 180, endAngle + 180, petal_color, -1);
    }

    // 显示结果
    cv::imshow("Sunflower", canvas);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

The code creates an 800x800 pixel canvas and uses OpenCV functions and methods to draw the sunflower pattern. cv::line()Draw straight lines, cv::circle()draw circles, cv::ellipse()draw semicircles and arcs.

5.4 Drawing a rabbit

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个800x800像素的画布
    cv::Mat canvas(800, 800, CV_8UC3, cv::Scalar(255, 255, 255));

    // 设置画笔属性
    int thickness = -1; // 填充形状
    cv::Scalar color(0, 0, 0); // 黑色
    int lineType = cv::LINE_8;

    // 绘制兔子的头部
    cv::Point center(400, 400);
    cv::circle(canvas, center, 60, color, thickness, lineType);

    // 绘制兔子的眼睛
    cv::Point eye1(380, 500);
    cv::Point eye2(420, 500);
    cv::circle(canvas, eye1, 25, color, thickness, lineType);
    cv::circle(canvas, eye2, 25, color, thickness, lineType);

    // 绘制兔子的嘴巴
    cv::Point mouth_center(400, 480);
    cv::Size axes(10, 10);
    cv::ellipse(canvas, mouth_center, axes, 0, 0, 180, color, thickness, lineType);

    // 绘制兔子的身体
    cv::circle(canvas, center, 100, color, thickness, lineType);

    // 绘制兔子的脚
    cv::Point foot1(340, 600);
    cv::Point foot2(460, 600);
    cv::ellipse(canvas, foot1, axes, 0, 0, 180, color, thickness, lineType);
    cv::ellipse(canvas, foot2, axes, 0, 0, 180, color, thickness, lineType);

    // 绘制兔子的尾巴
    cv::Point tail(480, 400);
    cv::circle(canvas, tail, 20, color, thickness, lineType);

    // 显示结果
    cv::imshow("Rabbit", canvas);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

The code creates an 800x800 pixel canvas and draws the bunny's head, eyes, mouth, body, feet, and tail.

5.5 Drawing Fairy Chang'e-Lite Version

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个800x800像素的画布
    cv::Mat canvas(800, 800, CV_8UC3, cv::Scalar(255, 255, 255));

    // 设置画笔属性
    int thickness = -1; // 填充形状
    cv::Scalar color(0, 0, 0); // 黑色
    int lineType = cv::LINE_8;

    // 绘制头部
    cv::Point head_center(400, 300);
    cv::circle(canvas, head_center, 80, color, thickness, lineType);

    // 绘制眼睛
    cv::Point eye1(360, 270);
    cv::Point eye2(440, 270);
    cv::circle(canvas, eye1, 10, color, thickness, lineType);
    cv::circle(canvas, eye2, 10, color, thickness, lineType);

    // 绘制嘴巴
    cv::Point mouth_center(400, 330);
    cv::Size axes(30, 30);
    cv::ellipse(canvas, mouth_center, axes, 0, 0, 180, color, thickness, lineType);

    // 绘制身体
    cv::Point body_top(400, 380);
    cv::Point body_bottom(400, 550);
    cv::line(canvas, body_top, body_bottom, color, 2, lineType);

    // 绘制衣裙
    cv::Point skirt_top(370, 550);
    cv::Point skirt_bottom(430, 700);
    cv::line(canvas, body_bottom, skirt_top, color, 2, lineType);
    cv::rectangle(canvas, cv::Rect(350, 570, 100, 130), color, thickness, lineType);

    // 绘制左手
    cv::Point hand1_start(400, 420);
    cv::Point hand1_end(320, 500);
    cv::line(canvas, hand1_start, hand1_end, color, 2, lineType);

    // 绘制右手
    cv::Point hand2_start(400, 420);
    cv::Point hand2_end(480, 500);
    cv::line(canvas, hand2_start, hand2_end, color, 2, lineType);

    // 绘制发髻
    cv::Point hair_top(400, 200);
    cv::Size hair_axes(80, 40);
    cv::ellipse(canvas, hair_top, hair_axes, 0, 180, 360, color, thickness, lineType);

    // 绘制发丝
    cv::Point hair1_start(400, 160);
    cv::Point hair1_end(320, 220);
    cv::line(canvas, hair1_start, hair1_end, color, 2, lineType);

    cv::Point hair2_start(400, 160);
    cv::Point hair2_end(480, 220);
    cv::line(canvas, hair2_start, hair2_end, color, 2, lineType);

    // 显示结果
    cv::imshow("Chang'e", canvas);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}


An 800x800 pixel canvas was created and the Fairy Chang'e's head, eyes, mouth, body, hands, dress and bun were drawn.

6. Summary

The Mid-Autumn Festival is one of the important festivals in traditional Chinese culture, and using OpenCV to draw exquisite mooncake and jade rabbit images is an innovative move that combines tradition and technology. Through the powerful functions of OpenCV, unique visual effects can be displayed, giving traditional elements a new charm. At the same time, this is also a unique expression of the Mid-Autumn Festival, allowing everyone to feel the surprise and fun brought to us by modern technology while tasting mooncakes and admiring the moon.

Whether you are a professional developer or an ordinary enthusiast, learning and mastering OpenCV can better unleash your imagination and creativity and create your own exquisite works. On this special Mid-Autumn Festival, with the help of the magic of OpenCV, you can feel the charm of traditional culture and the power of modern technology in the process of drawing moon cakes and jade rabbits. Use creativity and technology to add more joy and blessings to this wonderful festival.

In advance ----> I wish you all a happy Mid-Autumn Festival and a reunion for those under the full moon!

Guess you like

Origin blog.csdn.net/xiaolong1126626497/article/details/132874507