OpenCV 4.x API detailed explanation and C++ example-drawing function

Section 4 Drawing Functions

The drawing function is suitable for matrices/images of arbitrary depth. You can use anti-aliasing to render the boundaries of the shape (currently only implemented for 8-bit images). All functions include the parameter color (using RGB values ​​(which can be constructed using the Scalar constructor)) for color images and the brightness for grayscale images. For color images, the channel order is usually blue, green, and red. This is the expectation of imshow, imread and imwrite. Therefore, if you use the Scalar constructor to form a color, its appearance should be similar to:

Scalar ( b l u e _ c o m p o n e n t , g r e e n _ c o m p o n e n t , r e d _ c o m p o n e n t [ , a l p h a _ c o m p o n e n t ] ) \texttt{Scalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component]) Scalar(blue_component,green_component,red_component[,alpha_component])

If you use your own image rendering and I/O functions, you can use any channel order. The drawing function processes each channel independently, and does not depend on the order of the channels, or even the color space used. You can use cvtColor to convert the entire image from BGR to RGB or a different color space.

If part or all of the drawn figure is outside the image, the drawing function will crop it. Similarly, many drawing functions can handle pixel coordinates specified with sub-pixel precision. This means that coordinates can be passed as fixed-point numbers encoded as integers. The number of decimal places is specified by the shift parameter, and the calculation method of real point coordinates is Point (x, y) → Point2f (x ∗ 2 − ​​shift, y ∗ 2 − ​​shift) \texttt{Point}(x,y)\rightarrow\texttt {Point2f}(x*2^{-shift},y*2^{-shift})Point(x,and )Point2f(x2shift,Y2S h i f t )This function is particularly effective when rendering anti-aliased shapes.

Note that when the target image is 4 channels, these functions do not support alpha transparency processing. In this case, only copy color[3] to the redrawn pixel. Therefore, if you want to draw semi-transparent shapes, you can draw them in a separate buffer and then blend them with the main image.

1、cv::arrowedLine、cv::line


1) cv::arrowedLine : draw an arrow line segment from the first point to the second point.

void cv::arrowedLine(InputOutputArray img,Point pt1,Point pt2,const Scalar & color,int thickness = 1,int line_type = 8,int shift = 0,double tipLength = 0.1)

The function cv::arrowedLine draws an arrow between the pt1 and pt2 points of the image.

parameter name Parameter Description.
img The drawn image.
pt1 Starting point position
pt2 The point where the arrow points
color Line color
thickness Line thickness
line_type Line type, please refer to LineTypes
shift The number of decimal places in point coordinates.
tipLength The length of the arrow tip (relative to the length of the arrow)

2、cv::circle


Draw a circle by specifying the center position and radius.

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

parameter name Parameter Description
img The image used to draw a circle.
center Center position
radius radius
color colour
thickness The thickness of the circular profile (if positive). Negative values, such as FILLED , indicate that a solid circle is to be drawn.
lineType The type of circle border. Reference LineTypes
shift The number of decimal places in the center coordinate and radius value.
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 创建图像
    cv::Mat image = cv::Mat::zeros(cv::Size(512,512),CV_8UC3);

    // 绘制空心圆
    cv::circle(image,cv::Point(image.cols/2,image.rows/2),100,cv::Scalar(255,0,0),2);

    // 绘制实心圆
    cv::circle(image,cv::Point(image.cols/2,image.rows/2),75,cv::Scalar(0,255,0),-1);

    // 显示图像
    cv::imshow("src",image);
    cv::waitKey();
    cv::destroyAllWindows();
    return 0;
}

Insert picture description here

3、clipLine


Determine whether a straight line is within the rectangle.

bool cv::clipLine(Size imgSize,Point & pt1,Point & pt2)

The function cv::clipLine calculates a part of the line segment within the entire specified rectangle. If the line segment is completely outside the rectangle, false is returned. Otherwise, it returns true.

parameter name Parameter Description
imgSize Image size. The rectangle of the image is Rect(0, 0, imgSize.width, imgSize.height).
pt1 The first point
pt2 Second point

The other overloaded functions are as follows:

  • bool cv::clipLine(Rect imgRect,Point & pt1,Point & pt2)
  • bool cv::clipLine(Size2l imgSize,Point2l & pt1,Point2l & pt2)
	cv::Rect rect(0,0,200,100);
    cv::Point p1(10,10);
    cv::Point p2(203,105);
    cout << "is line in rectangle?"<<cv::clipLine(rect,p1,p2);

4、cv::drawContours


Draw outline outline or fill outline.

void cv::drawContours(InputOutputArray image,InputArrayOfArrays contours,int contourIdx,const Scalar & color,int thickness = 1,int lineType = LINE_8,InputArray hierarchy = noArray(),int maxLevel = INT_MAX,Point offset = Point())

If thickness ≥ 0, the function draws the contour contour in the image; if thickness <0, the function fills the area enclosed by the contour.

The parameters are as follows:

parameter name Parameter Description
image Target image
contours All input contours. Each contour is stored as a point vector.
contourIdx Indicates the parameters of the outline to be drawn. If it is negative, all contours are drawn.
color The color of the outline.
thickness The thickness of the line that draws the outline. If it is a negative number (for example, thickness = FILLED , the inside of the contour is drawn.
lineType Line connection type, refer to LineTypes
hierarchy Optional information about the hierarchy. Only needed if you only want to draw some contours (see maxLevel).
maxLevel The maximum level to draw the contour. If it is 0, only the specified outline is drawn. If it is 1, the function will draw contours and all nested contours. If it is 2, the function will draw contours, all nested contours, all nested-to-nested contours, and so on. This parameter is only considered if there is a hierarchical structure available.
offset Optional contour offset parameters. Move all drawn contours to the specified offset = (dx, dy).
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::String fileName = "images/leaf.jpg";
    cv::Mat src = cv::imread(fileName);
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
    if(src.data == NULL){
        printf("Image failed to read\n");
        return -1;
    }
    cv::imshow("src",src);

    cv::Mat dst = cv::Mat::zeros(src.rows, src.cols, CV_8UC3);


    vector<vector<cv::Point> > contours;
    vector<cv::Vec4i> hierarchy;

    // 阈值化图像
    cv::threshold(gray, gray, 100, 255, cv::THRESH_BINARY);

    // 查找轮廓
    cv::findContours( gray, contours, hierarchy,
                      cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE );
    cv::Scalar color(255,0,255);
    cv::drawContours( dst, contours,-1, color);

    // 显示图像
    cv::imshow("src",src);
    cv::imshow("dst",dst);
    cv::waitKey();
    cv::destroyAllWindows();

    return 0;
}

Insert picture description here

5 、 cv :: drawMarker


Draw a logo at the specified position.

void cv::drawMarker(InputOutputArray img,Point position,const Scalar & color,int markerType = MARKER_CROSS,int markerSize = 20,int thickness = 1,int line_type = 8)

The function cv::drawMarker draws a marker at a given position of the image. Several marker types are currently supported, please refer to MarkerTypes for more information.

type name Type description
MARKER_CROSS The crosshair marks the shape.
MARKER_TILTED_CROSS The 45-degree inclined crosshair marks the shape.
MARKER_STAR Star mark shape, combination of cross and oblique cross.
MARKER_DIAMOND Diamond mark shape.
MARKER_SQUARE Square mark shape.
MARKER_TRIANGLE_UP The upward triangle marks the shape.
MARKER_TRIANGLE_DOWN The downward-pointing triangle marks the shape.

The parameters are as follows:

parameter name Parameter Description.
img Drawn target image
position The anchor point of the crosshair.
color Line color
markType Marker type, please refer to MarkerTypes
thickness Line thickness
line_type Line type, please refer to LineTypes
markerSize The length of the marker axis [default = 20 pixels]
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 创建图像
    cv::Mat image(cv::Size(512,512),CV_8UC3);

    cv::Point center(image.cols / 2,image.rows / 2);

    // 绘制标记
    cv::drawMarker(image,center,cv::Scalar(0,0,255),cv::MarkerTypes::MARKER_CROSS,40,3);

    // 显示
    cv::imshow("image",image);
    cv::waitKey();
    cv::destroyAllWindows();

    return 0;
}

Insert picture description here

6 、 cv :: eclipse


Draw a simple or rough ellipse arc or filled ellipse sector.

void cv::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)

具有更多参数的函数cv :: ellipse会绘制椭圆轮廓,填充的椭圆,椭圆弧或填充的椭圆扇形。 绘图代码使用一般参数形式。 使用分段线性曲线来近似椭圆弧边界。 如果需要更多控制椭圆的渲染,则可以使用ellipse2Poly检索曲线,然后使用折线对其进行渲染或使用fillPoly对其进行填充。 如果您使用函数的第一个变体,并且想绘制整个椭圆而不是圆弧,请传递startAngle = 0和endAngle = 360。 如果startAngle大于endAngle,则会交换它们。 下图说明了绘制蓝色弧的参数的含义。

Insert picture description here

参数如下:

参数名称 参数描述
img 所要绘制的图像。
center 椭圆中心
axes 椭圆主轴尺寸的一半。
angle 椭圆旋转角度,以度为单位。
startAngle 椭圆弧的起始角度,以度为单位。
endAngle 椭圆弧的终止角度,以度为单位。
color 椭圆颜色
thickness 椭圆弧轮廓的粗细(如果为正)。 否则,这表明将绘制一个填充的椭圆形扇区。
lineType 椭圆边界线条样式。参考 LineTypes
shift 中心坐标和轴值中的小数位数。

另外的重载函数如下:

  • void cv::ellipse(InputOutputArray img,const RotatedRect & box,const Scalar & color,int thickness = 1,int lineType = LINE_8)
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 创建图像
    cv::Mat image(cv::Size(512,512),CV_8UC3);

    // 中心点
    cv::Point center(image.cols / 2 ,image.rows / 2);

    // 绘制椭圆
    cv::ellipse(image,center,cv::Size(image.cols / 2,image.rows / 4),
                45,0,360,cv::Scalar( 0, 0, 255 ),3);

    cv::ellipse(image,center,cv::Size(image.cols / 6,image.rows / 4),
                45,0,360,cv::Scalar( 0, 255, 0 ),-1);

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

Insert picture description here

6、cv::ellipse2Poly


用折线近似椭圆弧。

void cv::ellipse2Poly(Point center,Size axes,int angle,int arcStart,int arcEnd,int delta,std::vector< Point > & pts)

函数ellipse2Poly计算近似于指定椭圆弧的折线的顶点。 由椭圆使用。 如果arcStart大于arcEnd,则将它们交换。

参数如下:

参数名称 参数描述
center 弧的中心。
axes 椭圆主轴尺寸的一半。详细可以参考 ellipse
angle 椭圆的旋转角度,以度为单位。详细可以参考 ellipse
arcStart 椭圆弧的起始角度,以度为单位。
arcEnd 椭圆弧的终止角度,以度为单位。
delta 后续折线顶点之间的角度。 它定义了近似精度。
pts 折线顶点的输出向量。
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 创建图像
    cv::Mat image(cv::Size(512,512),CV_8UC3);

    // 中心点
    cv::Point center(image.cols / 2 ,image.rows / 2);
    vector<cv::Point2d> pts;

    // 生成椭圆近似折线
    cv::ellipse2Poly(center,cv::Size(image.cols/4,image.rows / 2),45,0,360,1,pts);

    cout <<"point.size:"<< pts.size() << endl;

    // 绘制
    for(int i = 0;i < pts.size() - 1;i++){
        cv::Point2d pt1 = pts[i];
        cv::Point2d pt2 = pts[i + 1];
        cv::line(image,pt1,pt2,cv::Scalar(0,0,255),3);
    }

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

    return 0;
}

Insert picture description here

7、cv::fillConvexPoly


填充凸多边形。

void cv::fillConvexPoly (InputOutputArray img,InputArray points,const Scalar & color,int lineType = LINE_8,int shift = 0)

函数cv :: fillConvexPoly绘制一个填充的凸多边形。 该函数比函数fillPoly快得多。 它不仅可以填充凸多边形,而且可以填充任何不具有自相交的单调多边形,即,其轮廓与每个水平线(扫描线)相交的多边形最多两次(尽管其最顶部和/或底部边缘可能是 水平)。

参数如下:

参数名称 参数类型
img 绘制图像
points 多边形顶点。
color 多边形颜色
lineType 多边形边界的线条类型. 参考LineTypes
shift 顶点坐标中的小数位数。
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 创建图像
    cv::Mat image(cv::Size(512,512),CV_8UC3);

    // 定义凸多边形顶点
    cv::Point PointArray[4];
    PointArray[0] = cv::Point(50,10);
    PointArray[1] = cv::Point(300,12);
    PointArray[2] = cv::Point(350,250);
    PointArray[3] = cv::Point(9,250);

    // 填充凸多边形。
    cv::fillConvexPoly(image,PointArray,4,cv::Scalar(0,255,0));

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

Insert picture description here

8、cv::fillPoly


填充以一个或多个多边形为边界的区域。

void cv::fillPoly(InputOutputArray img,InputArrayOfArrays pts,const Scalar & color,int lineType = LINE_8,int shift = 0,Point offset = Point())

函数cv :: fillPoly填充由多个多边形轮廓所界定的区域。 该功能可以填充复杂区域,例如,带有孔的区域,具有自相交的轮廓(部分轮廓)等等。

参数如下:

参数名称 参数描述
img 绘制图像。
pts 多边形数组,其中每个多边形都表示为点数组。
color 多边形颜色。
lineType 多边形边界的线条类型. 参考LineTypes
shift 顶点坐标中的小数位数。
offset 轮廓所有点的可选偏移量。
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    // 创建图像
    cv::Mat image(cv::Size(512,512),CV_8UC3);

    // 多边形顶点
    Point pts[1][6];
    pts[0][0] = Point(100, 100);
    pts[0][1] = Point(100, 200);
    pts[0][2] = Point(150, 250);
    pts[0][3] = Point(200, 200);
    pts[0][4] = Point(200, 100);
    pts[0][5] = Point(100, 100);
    const Point* ppts[] = { pts[0] }; //指针
    int npt[] = { 6 };
    Scalar color = Scalar(255, 0, 0);

    // 填充多边形
    fillPoly(image, ppts, npt, 1, color, 8);

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

Insert picture description here

9、cv::polylines


绘制多条多边形曲线。

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

参数名称 参数描述
img 所要绘制的图像
pts 多边形曲线数组。
isClosed 指示绘制的折线是否闭合的标志。 如果它们是闭合的,则该函数将从每个曲线的最后一个顶点到其第一个顶点绘制一条直线。
color 折线颜色。
thickness 折线边缘的厚度。
lineType 线段的类型。请参考 LineTypes
shift 顶点坐标中的小数位数。
#include <opencv2/opencv.hpp>

using namespace std;

int main(void)
{
        // 创建图像
        cv::Mat	image(512, 512, CV_8UC3);

        // 多边形顶点
        vector<cv::Point> p;
        int n = 5;
        for (int i = 0; i < n; i++) {
                p.push_back(cv::Point(cos(CV_PI * (2.0*i/n - 0.5)) * 180 + 200, sin(CV_PI * (2.0*i/n - 0.5)) * 180 + 200));
        }

        // 绘制多边形
        cv::polylines(image, p, true, cv::Scalar(255, 0, 0), 2, cv::LINE_AA);

        p.clear();
        for (int i = 0; i < n; i++) {
                p.push_back(cv::Point(cos(CV_PI * (2.0*i/n - 0.5)) * 140 + 200, sin(CV_PI * (2.0*i/n - 0.5)) * 140 + 200));
        }

        // 填充多边形
        cv::fillConvexPoly(image, p, cv::Scalar(0, 0, 255), cv::LINE_AA);

        cv::imshow("image", image);

        vector<vector<cv::Point>> ps(16);
        for (int n = 0; n < 16; n++) {
                cv::Point p0((n % 4) * 100 + 50, (n / 4) * 100 + 50);
                for (int i = 0; i < n + 3; i++) {
                        cv::Point pa(cos(CV_PI * (2.0*i/(n+3) - 0.5)) * 40, sin(CV_PI * (2.0*i/(n+3) - 0.5)) * 40);
                        ps[n].push_back(p0 + pa);
                }
        }

        image = cv::Scalar(255, 255, 255);


        cv::fillPoly(image, ps, cv::Scalar(0, 255, 255), cv::LINE_AA);
        cv::polylines(image, ps, true, cv::Scalar(0, 0, 0), 3, cv::LINE_AA);

        cv::imshow("image2", image);
        cv::waitKey();
        cv::destroyAllWindows();

        return 0;
}

Insert picture description here

10、cv::getFontScaleFromHeight、cv::getTextSize、cv::putText


1)cv::getFontScaleFromHeight:计算用于实现给定高度(以像素为单位)的特定于字体的大小。

double cv::getFontScaleFromHeight(const int fontFace,const int pixelHeight,const int thickness = 1)

参数名称 参数描述
fontFace 使用的字体, 请参考 cv::HersheyFonts.
pixelHeight 像素高度,用于计算fontScale
thickness 用于渲染文本的线的粗细。有关详细信息,请参见putText。

2)cv::getTextSize:计算文本字符串的宽度和高度(包含指定文本的框的大小)。

Size cv::getTextSize(const String & text,int fontFace,double fontScale,int thickness,int * baseLine)

参数如下:

参数名称 参数描述
text 所要绘制的图像
fontFace 所要使用的字体。 请参考 HersheyFonts.
fontScale 字体比例因子乘以特定于字体的基本大小。
thickness 用于渲染文本的线的粗细。 请详细参考 putText
[out] baseLine 基线相对于最底下的文本点的y坐标。

函数cv :: getTextSize计算并返回包含指定文本的框的大小。 也就是说,以下代码呈现了一些文本,其周围的紧实框和基线:

String text = "Funny text inside the box";
int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
double fontScale = 2;
int thickness = 3;
Mat img(600, 800, CV_8UC3, Scalar::all(0));
int baseline=0;
Size textSize = getTextSize(text, fontFace,
                            fontScale, thickness, &baseline);
baseline += thickness;
// center the text
Point textOrg((img.cols - textSize.width)/2,
              (img.rows + textSize.height)/2);
// draw the box
rectangle(img, textOrg + Point(0, baseline),
          textOrg + Point(textSize.width, -textSize.height),
          Scalar(0,0,255));
// ... and the baseline first
line(img, textOrg + Point(0, thickness),
     textOrg + Point(textSize.width, thickness),
     Scalar(0, 0, 255));
// then put the text itself
putText(img, text, textOrg, fontFace, fontScale,
        Scalar::all(255), thickness, 8);

3)cv::putText:绘制文本字符串。

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

函数cv :: putText在图像中呈现指定的文本字符串。 无法使用指定字体呈现的符号将替换为问号。 有关文本呈现代码示例,请参见getTextSize。

参数如下:

参数名称 参数描述
img 绘制的图像.
text 气概绘制的文本
org 图像中文本字符串的左下角。
fontFace 所要使用的字体。 请参考 HersheyFonts.
fontScale 字体比例因子乘以特定于字体的基本大小。
color 文本颜色
thickness 用于绘制文本的线条的粗细。
lineType 线条类型,请参考LineTypes
bottomLeftOrigin 如果为true,则图像数据原点位于左下角。 否则,它位于左上角。
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    //创建空白图用于绘制文字
    cv::Mat image = cv::Mat::zeros(cv::Size(640, 480), CV_8UC3);
    //设置蓝色背景
    image.setTo(cv::Scalar(100, 0, 0));

    //设置绘制文本的相关参数
    std::string text = "Hello World!";
    int font_face = cv::FONT_HERSHEY_COMPLEX;
    double font_scale = 2;
    int thickness = 2;
    int baseline;
    //获取文本框的长宽
    cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);

    //将文本框居中绘制
    cv::Point origin;
    origin.x = image.cols / 2 - text_size.width / 2;
    origin.y = image.rows / 2 - text_size.height / 2;
    cv::putText(image, text, origin, font_face, font_scale, cv::Scalar(0, 255, 255), thickness, 8, 0);

    //显示绘制解果
    cv::imshow("image", image);
    cv::waitKey(0);
    return 0;
}

Insert picture description here

11、cv::rectangle

绘制一个简单的,粗的或实心的直角矩形。

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

函数cv :: rectangle绘制一个矩形轮廓或一个填充的矩形,其两个相对角为pt1和pt2。

参数如下:

参数名称 参数描述
img 所要绘制的图像.
pt1 矩形的顶点。
pt2 与pt1相反的矩形的顶点。
color 矩形的颜色或亮度(灰度图像)。
thickness The thickness of the lines that make up the rectangle. Negative values, such as FILLED , indicate that the function must draw a filled rectangle.
lineType Line type, please refer to LineTypes
shift The number of decimal places in point coordinates.

Other overloaded functions are as follows:

  • void cv::rectangle (InputOutputArray img,Rect rec,const Scalar & color,int thickness = 1,int lineType = LINE_8,int shift = 0)
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    //创建图像
    cv::Mat image = cv::Mat::zeros(cv::Size(640, 480), CV_8UC3);

    // 绘制空心矩形
    cv::rectangle(image,cv::Point(100,100),cv::Point(300,300),cv::Scalar(0,255,0),3);

    // 填充矩形
    cv::rectangle(image,cv::Point(120,120),cv::Point(280,280),cv::Scalar(0,0,255),-1);

    //显示绘制
    cv::imshow("image", image);

    cv::waitKey();
    cv::destroyAllWindows();

    return 0;
}

Insert picture description here

Guess you like

Origin blog.csdn.net/wujuxKkoolerter/article/details/112300606