OpenCV Notes (3): Drawing of basic graphics

Part11. Draw simple graphics

The drawing function is the most basic function of OpenCV. OpenCV provides basic drawing functions to help us draw some basic graphics. Through the combination of these functions, we can also make some advanced applications.

11.1 Drawing points and circles

The drawing function of OpenCV is relatively simple, and many parameters are very similar. Therefore, when introducing the first function, the meaning of each parameter will be introduced in detail, and I will not give a particularly detailed introduction later.

Let’s first look at the drawing of points and circles:

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

using namespace std;
using namespace cv;

int main(int argc,char *argv[])
{
    Mat image = Mat::zeros(Size(800, 800), CV_8UC3);
    image.setTo(255);// 设置屏幕为白色

    Point p1(100, 100);
    Point p2(200, 200);
    Point p3(300, 300);
    Point p4(400, 400);
    Point p5(500, 500);
    Point p6(600, 600);
    Point p7(700, 700);

    circle(image, p1, 4, Scalar(0, 0, 255), -1);  // 画半径为4的圆(画点)

    circle(image, p2, 60, Scalar(255, 0, 0), 2);  // 画半径为60的圆

    circle(image, p3, 60, Scalar(0, 255, 0), -1);

    circle(image, p4, 60, Scalar(255, 255, 0), 5);

    circle(image, p5, 60, Scalar(255, 0, 255), -1);

    circle(image, p6, 60, Scalar(0, 255, 255), 2);

    circle(image, p7, 60, Scalar(0, 0, 0), -1);

    imshow("src", image);

    waitKey(0);
    return 0;
}
a779d7e5bcfac88f5b5cc6ef079fb386.jpeg
Draw points and circles.png

We mainly use the circle() function to draw points and circles.

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

The meaning of each parameter:

The first parameter img: the input source image. The second parameter center: the coordinates of the center of the circle. The third parameter radius: the radius of the circle. The fourth parameter color: the color of the circle. The fifth parameter thickness: if it is a positive number, it indicates the thickness of the lines that make up the circle. If it is negative, it means the circle is filled. The sixth parameter lineType: the type of line. OpenCV provides three types of lines, all of which are LineTypes enumeration types.

  • LINE_4: 4, indicating four connecting lines.

  • LINE_8: 8, indicating eight connecting lines.

  • LINE_AA: 16, represents anti-aliasing line. Using it will produce better drawing quality and the image will look very smooth, but the drawing speed will be slower.

The seventh parameter shift: the number of decimal points for the circle center coordinate point and radius value.

Many parameters here will be used in subsequent functions in this article.

21.2 Drawing straight lines

The difference between a straight line and a circle is that a straight line requires 2 points to determine its position. Here is an example of drawing a straight line:

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

using namespace std;
using namespace cv;

int main(int argc,char *argv[])
{
    Mat image = Mat::zeros(Size(800, 800), CV_8UC3);
    image.setTo(255);// 设置屏幕为白色

    Point p1(100, 100);
    Point p2(700, 700);
    Point p3(700, 100);
    Point p4(100, 700);

    line(image, p1, p2, Scalar(0, 0, 255), 2);
    line(image, p3, p4, Scalar(255, 0, 0), 2);

    imshow("src", image);

    waitKey(0);
    return 0;
}
d223749b8fe9dd069ae7e38b411c234c.jpeg
Draw a straight line.png

31.3 Drawing a rectangle

There are two ways to draw a rectangle. One is to define the position of the upper left corner of the rectangle and the length and width of the rectangle, and then draw it on the image; the other is to determine the position of the rectangle by determining the upper left corner and lower right corner of the rectangle. , and then plot it on the image.

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

using namespace std;
using namespace cv;

int main(int argc,char *argv[])
{
    Mat image = Mat::zeros(Size(800, 800), CV_8UC3);
    image.setTo(255);// 设置屏幕为白色

    Rect rect(150, 150, 120, 200);
    rectangle(image, rect, Scalar(0, 0, 255), 4);

    rectangle(image,Point(200,400),      //两个对角点
              Point(600,600),
              Scalar(255,0,0),
              -);

    imshow("src", image);

    waitKey(0);
    return 0;
}
74a6300a8a32fbb15b35725248a5db2c.jpeg
Draw rectangle.png

41.4 Drawing ellipses

Drawing an ellipse is a little more complicated. In addition to the center position of the ellipse, you also need to determine the rotation angle, horizontal axis length, and vertical axis length of the ellipse, so that you can draw the ellipse.

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

using namespace std;
using namespace cv;

int main(int argc,char *argv[])
{
    Mat image = Mat::zeros(Size(800, 800), CV_8UC3);
    image.setTo(255);// 设置屏幕为白色

    Point p1(100, 100);
    Point p2(200, 200);
    Point p3(300, 300);
    Point p4(400, 400);
    Point p5(600, 600);

    ellipse(image,p1,Size(60, 30),30,0,360,Scalar(255, 255, 0),4);

    ellipse(image,p2,Size(30, 60),0,0,360,Scalar(255, 0, 0),-1);

    ellipse(image,p3,Size(60, 30),120,0,360,Scalar(0, 255, 0),4);

    ellipse(image,p4,Size(100, 100),0,0,360,Scalar(0, 0, 255),-1);

    ellipse(image,p5,Size(120, 60),0,0,360,Scalar(255, 0, 255),4);

    imshow("src", image);

    waitKey(0);
    return 0;
}
05d9454bb5ea9261364d8f4e0b417e91.jpeg
Draw ellipse.png

Definition of the ellipse() function for drawing ellipses:

CV_EXPORTS_W 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);

Among them, the third parameter axes: The two parameters of Size are the length of the horizontal axis and the length of the vertical axis. When the horizontal axis and the vertical axis are equal, it means a circle. The fourth parameter angle: ellipse rotation angle. The fifth parameter startAngle: the starting point of the elliptical arc measured clockwise from the main axis. The sixth parameter endAngle: the end point of the elliptical arc measured clockwise from the main axis. When the values ​​of startAngle and endAngle are 0 and 360, a complete ellipse will be drawn.

51.5 Drawing polygons

Polyhedrons are more complex than ellipses, and there are two functions that can be used to draw polyhedrons.

The polylines() function draws multiple connected line segments based on the point set to form a polyhedron, and the fillPoly() function draws a polyhedron with a filling effect. Therefore, whether the thickness parameter is negative will not affect the filling of the polyhedron.

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

using namespace std;
using namespace cv;

int main(int argc,char *argv[])
{
    Mat image = Mat::zeros(Size(800, 800), CV_8UC3);
    image.setTo(255);// 设置屏幕为白色

    Point p1(100, 100);
    Point p2(350, 100);
    Point p3(450, 280);
    Point p4(320, 450);
    Point p5(100, 400);

    std::vector<Point> pts;
    pts.push_back(p1);
    pts.push_back(p2);
    pts.push_back(p3);
    pts.push_back(p4);
    pts.push_back(p5);

    polylines(image, pts, true, Scalar(255, 0, 255), 4);

    Point p6(500, 500);
    Point p7(720, 650);
    Point p8(650, 780);
    Point p9(550, 700);
    Point p10(300, 700);

    pts.clear();
    pts.push_back(p6);
    pts.push_back(p7);
    pts.push_back(p8);
    pts.push_back(p9);
    pts.push_back(p10);

    fillPoly(image, pts, Scalar(0, 255, 255));

    imshow("src", image);

    waitKey(0);
    return 0;
}
8be97244227cb5eb80ae3af732b33e1d.jpeg
Draw polygon.png

Let’s briefly introduce the polylines() function. The other fillPoly() function is very similar.

CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts,
                            bool isClosed, const Scalar& color,
                            int thickness = 1, int lineType = LINE_8, int shift = 0 );

The second parameter pts: the set of points of the input polygon. The third parameter isClosed: whether to connect multiple drawn line segments end to end. If you want to draw a polygon, this parameter is very important and needs to be set to true.

61.6 Adding text to images

OpenCV provides the putText() function for adding text to the original image, and supports the setting of font and font size.

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

using namespace std;
using namespace cv;

int main(int argc,char *argv[])
{
    Mat image = Mat::zeros(Size(800, 800), CV_8UC3);
    image.setTo(255);// 设置屏幕为白色

    string text = "Hello OpenCV!";

    putText(image, text, Point(0,100), FONT_HERSHEY_PLAIN, 2, cv::Scalar(0, 0, 255), 2);
    putText(image, text, Point(100,200), FONT_HERSHEY_PLAIN, 4, cv::Scalar(255, 0, 255), 4);

    //设置绘制文本的相关参数
    int fontFace = cv::FONT_HERSHEY_SIMPLEX;
    double fontScale = 2;
    int thickness = 8;
    int baseline;

    // 通过 getTextSize() 函数先获取待绘制文本的大小
    Size textSize = getTextSize(text, fontFace, fontScale, thickness, &baseline);

    // 计算出文本绘制到图片居中的位置
    Point point;
    point.x = image.cols / 2 - textSize.width / 2;
    point.y = image.rows / 2 + textSize.height / 2;

    putText(image, text, point, fontFace, fontScale, cv::Scalar(255, 255, 0), thickness);

    imshow("src", image);

    waitKey(0);
    return 0;
}
eec31b4fa964a3b448646cb9c021722d.jpeg
Add text.png

Part22. Introduction to contours and drawing contours

72.1 Getting Started with Silhouettes

Contours are a common concept in machine vision . It is a curve consisting of a series of connected points, all of the same color or grayscale. Contours are commonly used for tasks such as shape analysis, object detection, and recognition.

In general, in order to obtain accurate contours, the image needs to be binarized first, such as using threshold segmentation or Canny edge detection to obtain a binary image . Then, contour discovery and contour analysis are performed on the binary image.

Contour discovery uses the findContours() function to detect object boundaries in the image and stores each contour as a point vector. Therefore, the topological information of an image can be obtained, including the index number of the next contour, the previous contour, the parent contour and the embedded contour of a contour.

After obtaining the image contour, we can analyze and filter the contour through the attributes of the contour (such as the area, centroid, perimeter, geometric moment, central moment, etc.) of the contour. Contours have many attributes and properties. We will introduce more details in subsequent articles. This article is just a simple introduction.

The following example shows obtaining the outline of a mobile phone, obtaining its minimum enclosing rectangle and intercepting ROI:

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

using namespace std;
using namespace cv;

bool ascendSort(vector<Point> a,vector<Point> b)
{
    return contourArea(a) > contourArea(b);
}

int main(int argc,char *argv[])
{
    string fileName = ...;
    Mat image = imread(fileName);
    if (image.empty()) {
        return -1;
    }

    imshow("src",image);

    Mat gray;
    cvtColor(image,gray,COLOR_BGR2GRAY);
    Mat thresh;
    threshold(gray, thresh, 0, 255, THRESH_BINARY | THRESH_OTSU);

    // 定义变量轮廓
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;

    findContours(thresh, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
    sort(contours.begin(), contours.end(), ascendSort);//ascending sort

    RotatedRect rrt = minAreaRect(contours[0]);
    Rect bbox = rrt.boundingRect();

    Mat roi;
    try {
        roi = image(bbox);
    } catch (...) {
        return -1;
    }

    imshow("roi",roi);

    waitKey(0);

    return 0;
}
88699634566ee0b58532d3210575d96b.jpeg
FindROI.png

The above code first converts the original image into a grayscale image, and then performs threshold segmentation into a binary image. Then, the contours are searched and sorted according to the size of the contour area. Finally, obtain the minimum enclosing rectangle of the largest contour and intercept this minimum enclosing rectangle as ROI and display it.

In this code, the functions and explanations of some functions will be introduced in detail in subsequent sections. This article only explains in detail how to discover and search contours, mainly using the findContours() function. It contains many parameters, and we need to briefly introduce the meaning of each parameter.

The first parameter image: the input source image. A single channel image of CV_8UC1. The second parameter contours: output contour image. Each contour is stored as a point vector std::vector< cv::Point >, and the entire output contour std::vector<std::vector < cv::Point >> is composed of multiple contours. The third parameter hierarchy: outputs the inheritance relationship of each contour. It is a vector of type std::vector < cv::Vec4i >. The length is consistent with the length of contours. Each element corresponds to the element of contours and contains information about the image topology. The fourth parameter mode: the mode of contour detection. Includes the following four types:

  • RETR_EXTERNAL: Only detect the outer contour and ignore holes inside the contour.

  • RETR_LIST: Detect all contours, but do not establish inheritance (inclusion) relationships.

  • RETR_TREE: Detect all contours and establish all inheritance (inclusion) relationships.

  • RETR_CCOMP: Detect all contours, but only establish two levels of inclusion relationships.

  • RETR_FLOODFILL: flood filling method. When using this mode, the input source image can also be a 32-bit integer image (CV_32SC1).

The fifth parameter method: encoding information for each contour. Includes the following four types:

  • CHAIN_APPROX_NONE: Store all points on the contour.

  • CHAIN_APPROX_SIMPLE: Only the inflection points on the contour are stored.

  • CHAIN_APPROX_TC89_L1: Use teh-Chinl chain approximation algorithm.

  • CHAIN_APPROX_TC89_KCOS uses the teh-Chinl chain approximation algorithm.

The sixth parameter offset: the offset of each contour point movement. Indicates the offset of all contour information relative to the original image. It is an optional parameter, cv::Point() type.

82.2 Drawing contours

After the above code finds the contour, drawing the contour becomes very simple. We can draw contours using the drawContours() function.

drawContours(image,contours,0,Scalar(0,0,255),8);

imshow("contours",image);

Combined with the imshow() function, the drawn outline of the mobile phone can be displayed directly on the original image.0a5cdaa44f2f9cfdfb97d9c7b666272f.jpeg

The parameters of the drawContours() function will not be explained one by one. We only explain the meaning of the two parameters. The second parameter contours: input all contour images. The third parameter contourIdx: contour index number, starting from 0. -1 means draw all contours.

Through this function, we learn to draw contours. When debugging code, I often draw the relevant outlines found on the original image to see if the content found is accurate.

Part33. Summary

This article is mainly divided into two parts. The first part introduces the basic drawing functions and usage of OpenCV. Their use is relatively simple as long as you understand the meaning of each parameter in each function. If you combine these functions, you can also make some relatively advanced applications.

The second part introduces the introductory knowledge of contours, mainly contour discovery and contour drawing. Contours are one of the core contents of image processing. They contain a lot of important information and properties, which we will focus on in subsequent articles.

Guess you like

Origin blog.csdn.net/SLFq6OF5O7aH/article/details/134002044