目录

1. 概述

2. 绘图函数

3. 使用举例

3.1  arrowedLine

3.2  circle

3.3  clipLine

3.4  drawContour

3.5  drawMarker

3.6  ellipse

3.7  ellipse2Poly

3.8  fillConvexPoly

3.9  fillPoly

3.10 getFontScaleFromHeight  

3.11 getTextSize

3.12 line

3.13 polylines

3.14 putText

3.15 rectangle


1. 概述

    绘图函数可处理任意深度的矩阵/图像。形状边界可使用抗锯齿渲染(目前仅支持 8 位图像)。所有函数都包含一个名为 color 的参数,该参数对于彩色图像使用 RGB 值(可使用Scalar构造函数创建),对于灰度图像使用亮度值。对于彩色图像,通道顺序通常为蓝(Blue)、绿(Green)、红(Red)Imshowimreadimwrite 函数均遵循此顺序。因此,如果你使用Scalar构造函数创建颜色,其格式应如下所示:

Scalar( blue_component , green_component , red_component , alpha_component)

    如果你使用的是自定义的图像渲染和 I/O 函数,则可以使用任意的通道顺序。绘图函数会独立处理每一个通道,既不依赖于通道顺序,甚至也不依赖于所使用的色彩空间。你可以使用 cvtColor 函数将整幅图像从 BGR 转换为 RGB,或转换为其他色彩空间

    如果绘制的图形部分或全部超出图像范围,绘图函数会对其进行裁剪。此外,许多绘图函数可以处理以亚像素(sub-pixel)精度指定的像素坐标。这意味着坐标可以作为定点数传递,并以整数形式编码。小数位数由移位参数指定,实际的点坐标计算如下

  \rm{Point}(x,y) \longrightarrow \rm{Point2f}( x*2^{-shift},y *2^{-shift} )

该功能在渲染抗锯齿形状时特别有效

    当目标图像为 4 通道时,这些函数不支持 α 透明度。在这种情况下,颜色会被简单地复制到重绘的像素。因此,如果要绘制半透明形状,可以将其绘制在单独的缓冲区中,然后再与主图像混合。

2. 绘图函数

函数

说明

arrowedLine

画一个从第一点指向第二点的箭头。

circle

画一个圆

clipLine

将线条裁剪到图像矩形框内。

drawContour

绘制轮廓线或填充轮廓线。

drawMarker

在图像中预先设定的位置绘制标记。

ellipse

绘制简单或粗椭圆弧,或填充椭圆扇形。

ellipse2Poly

用折线近似椭圆弧。

fillConvexPoly

填充凸多边形。

fillPoly

填充由一个或多个多边形围成的区域

getFontScaleFromHeight

计算达到给定像素高度所需的字体尺寸。

getTextSize

计算文本字符串的高度和宽度

line

绘制连接两点的一条线段

polylines

绘制若干条折线

putText

绘制文本字符串

rectangle

绘制一个简单的、粗线条的或实心的直立矩形。

3. 使用举例

3.1  arrowedLine

#include <opencv2/opencv.hpp>

using namespace cv;

int Test_arrowedLine()

{

          // 1. 创建一幅 400x400 黑色图像 (3 通道, 8位)

          Mat img = Mat::zeros(400, 400, CV_8UC3);

          // 2. 定义箭头起止点

          Point start_point(50, 50);

          Point end_point(350, 350);

          // 3. 绘制箭头

          // 参数: img, pt1, pt2, color, thickness, line_type, shift, tipLength

          arrowedLine(img,

                    start_point,

                    end_point,

                    Scalar(0, 255, 0), // 绿色 (BGR)

                    3,                 // 厚道

                    8,                 // 线型 (8连通)

                    0,                 // 平衡

                    0.1);              // 箭尖长度(占箭身全长的比例)

          // 4. 显示结果

          imshow("Arrowed Line Example", img);

          waitKey(0); // Wait for a key press to close

          return 0;

}

运行结果:

3.2  circle

#include <opencv2/opencv.hpp>

#include <iostream>

int Test_circle()

{

          // 1. 创建一幅黑色图像 (512x512, 3 通道)

          Mat image = Mat::zeros(512, 512, CV_8UC3);

          // 2. 定义圆之参数

          Point center(256, 256);

          int radius = 100;

          Scalar blue(255, 0, 0);

          Scalar red(0, 0, 255);

          // 3. 画一个蓝色的圆形轮廓(thickness = 3)

          // circle(img, center, radius, color, thickness, lineType)

          circle(image, center, radius, blue, 3, LINE_AA);

          // 4. 画一个红色填充的小圆 (thickness = FILLED or -1)

          circle(image, Point(100, 100), 50, red, FILLED);

          // 5.显示结果

          imshow("OpenCV Circle Example", image);

          waitKey(0);

          return 0;

}

运行结果:

3.3  clipLine

int Test_clipLine()

{

          // 1. 定义裁剪区域(图像尺寸或具体矩形)

          cv::Size imgSize(400, 400);

          cv::Rect imgRect(0, 0, 400, 400);

          // 2. 定义一条起/止于边界之外的线段

          cv::Point pt1(-50, -50);

          cv::Point pt2(500, 500);

          // 3. 为了便于可视创建一幅黑色图像

          cv::Mat image = cv::Mat::zeros(imgSize, CV_8UC3);

          // 4. 裁剪线段

          // The points pt1 and pt2 are modified IN-PLACE to their clipped coordinates

          bool isVisible = cv::clipLine(imgSize, pt1, pt2);

          if (isVisible) {

                    // Draw the clipped line on the image

                    cv::line(image, pt1, pt2, cv::Scalar(0, 255, 0), 2);

                    std::cout << "Clipped Points: " << pt1 << " to " << pt2 << std::endl;

          }

          else {

                    std::cout << "The line is completely outside the boundary." << std::endl;

          }

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

          cv::waitKey(0);

          return 0;

}

运行结果:

3.4  drawContour

int Test_drawContour()

{

          // 1. 载入一幅图像并转换为恢度图像

          cv::Mat src = cv::imread("D:\\TestVideo\\Flower4.jpg");

          cv::Mat gray, binary;

          cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);

          // 2.转换为二值图像(在黑色背景上的白色物体中查找轮廓)

          cv::threshold(gray, binary, 100, 255, cv::THRESH_BINARY);

          // 3. 找查轮廓

          std::vector<std::vector<cv::Point>> contours;

          std::vector<cv::Vec4i> hierarchy;

          cv::findContours(binary, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);

          // 4. 创建一个用于绘图的空白黑色图像。

          cv::Mat drawing = cv::Mat::zeros(binary.size(), CV_8UC3);

          // 5. 绘制轮廓

          // -1 draws ALL contours; (0, 255, 0) is Green; 2 is thickness

          cv::drawContours(drawing, contours, -1, cv::Scalar(0, 255, 0), 2);

          // 绘制并填充特定轮廓(例如,第一个)

          if (!contours.empty()) {

                    cv::drawContours(drawing, contours, 0, cv::Scalar(255, 0, 0), cv::FILLED);

          }

          cv::imshow("Contours", drawing);

          cv::waitKey(0);

          return 0;

}

下面是原图像和运行结果:


3.5  drawMarker

int Test_drawMarker()

{

          // 创建一幅 400x400 黑色图像

          Mat img = Mat::zeros(400, 400, CV_8UC3);

          // 定义标记属性

          Point position(200, 200);      // 图像中心

          Scalar color(0, 255, 0);       //绿色 (BGR)

          int markerType = MARKER_CROSS; // 预定义标记类型

          int markerSize = 20;           // 像素中的标记大小

          int thickness = 2;             // 线厚度

          // 绘制一个绿色十字标记。

          drawMarker(img, position, color, markerType, markerSize, thickness);

          // 绘制另一个标记(红色菱形)的示例

          drawMarker(img, Point(100, 100), Scalar(0, 0, 255), MARKER_DIAMOND, 30, 2);

          // 显示结果

          imshow("OpenCV drawMarker Example", img);

          waitKey(0);

          return 0;

}

运行结果:

3.6  ellipse

int Test_ellipse()

{

          // 创建一幅黑色图像 (600x600)

          cv::Mat img = cv::Mat::zeros(600, 600, CV_8UC3);

          // Parameters:

          // 1. Image

          // 2. Center point (x, y)

          // 3. Axes lengths (half-major axis, half-minor axis)

          // 4. Rotation angle (degrees)

          // 5. Start angle of arc (degrees)

          // 6. End angle of arc (degrees)

          // 7. Color (B, G, R)

          // 8. Thickness (use -1 or cv::FILLED for a filled ellipse)

          cv::ellipse(img, cv::Point(300, 300), cv::Size(200, 100), 45, 0, 360, cv::Scalar(0, 0, 255), 2);

          // Define an ellipse using a RotatedRect (center, size, angle)

          cv::RotatedRect box(cv::Point2f(300, 300), cv::Size2f(400, 200), 30);

          cv::ellipse(img, box, cv::Scalar(0, 255, 0), 2, cv::LINE_AA);

          std::vector<cv::Point> points; // Suppose these are contour points

          if (points.size() >= 5) { // fitEllipse requires at least 5 points

                    cv::RotatedRect fittedEllipse = cv::fitEllipse(points);

                    cv::ellipse(img, fittedEllipse, cv::Scalar(0, 0, 255), 2);

          }

          cv::imshow("Ellipse Example", img);

          cv::waitKey(0);

          return 0;

}

运行结果:


3.7  ellipse2Poly

int Test_ellipse2Poly()

{

          // 创建一幅黑色图像

          cv::Mat image = cv::Mat::zeros(400, 400, CV_8UC3);

          // 绘制椭圆的参数

          cv::Point center(200, 200);

          cv::Size axes(100, 50);

          int angle = 30;      // Rotation angle of the ellipse

          int arcStart = 0;    // Starting angle of the arc

          int arcEnd = 360;    // Ending angle of the arc (360 for full ellipse)

          int delta = 5;       // Angle between subsequent polyline vertices

          // 存储最终的点

          std::vector<cv::Point> pts;

          // 根据椭圆定义生成折线点

          cv::ellipse2Poly(center, axes, angle, arcStart, arcEnd, delta, pts);

          // 在图上绘制折线

          // Note: polylines() expects a vector of vectors or an array of points

          std::vector<std::vector<cv::Point>> polylines_pts = { pts };

          cv::polylines(image, polylines_pts, true, cv::Scalar(0, 255, 0), 2, cv::LINE_AA);

          // Display the result

          cv::imshow("Ellipse to Polyline", image);

          cv::waitKey(0);

          return 0;

}

运行结果:

3.8  fillConvexPoly

int Test_fillConvexPoly()

{

          // 1. 创建一幅黑色图像 (500x500)

          cv::Mat image = cv::Mat::zeros(500, 500, CV_8UC3);

          // 2. 定义凸多边形顶点 (例如., 一个三角形)

          // 点必须按顺序排列在周长上。

          std::vector<cv::Point> points;

          points.push_back(cv::Point(250, 100)); // 顶部

          points.push_back(cv::Point(400, 400)); // 底部右角

          points.push_back(cv::Point(100, 400)); // 底部左角

          // 3. 填充凸多边形

          // Parameters: (target_image, points_vector, color, line_type, shift)

          cv::fillConvexPoly(image,

                    points,

                    cv::Scalar(0, 255, 0), // Green color (BGR)

                    cv::LINE_AA,               // 抗锯齿线条

                    0);                        // 平移

          // 4. Display the result

          cv::imshow("Filled Convex Polygon", image);

          cv::waitKey(0);

          return 0;

}

运行结果:

3.9  fillPoly

int Test_fillPoly()

{

          // 1. 创建一幅黑色图像 (400x400)

          cv::Mat image = cv::Mat::zeros(400, 400, CV_8UC3);

          //// 2. 定义一个三角形之顶点

          //std::vector<cv::Point> triangle;

          //triangle.push_back(cv::Point(200, 50));

          //triangle.push_back(cv::Point(350, 350));

          //triangle.push_back(cv::Point(50, 350));

          //// 2. 定义一个不规则四边形之顶点

          std::vector<cv::Point> quadrangle;

          quadrangle.push_back(cv::Point(200, 10));

          quadrangle.push_back(cv::Point(300, 100));

          quadrangle.push_back(cv::Point(200, 210));

          quadrangle.push_back(cv::Point(100, 100));

          // 3. fillPoly 期望接收一个多边形列表(即向量的向量)。

          std::vector<std::vector<cv::Point>> pts;

          pts.push_back(quadrangle);

          // 4. 绘制填充多边形

          // Parameters: image, points, color (BGR), lineType

          cv::fillPoly(image, pts, cv::Scalar(0, 255, 0), cv::LINE_8);

          // 5. Display the result

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

          cv::waitKey(0);

          return 0;

}

运行结果:

3.10 getFontScaleFromHeight  

int Test_getFontScaleFromHeight()

{

          // 1. 创建一幅黑色图像

          cv::Mat image = cv::Mat::zeros(300, 600, CV_8UC3);

          image.setTo(cv::Scalar(50, 50, 50)); // 深灰色背景

          std::string text = "Hello OpenCV!";

          int fontFace = cv::FONT_HERSHEY_SIMPLEX;

          int targetHeight = 50; // 像素中的目标高度

          int thickness = 2;

          cv::Point org(50, 150); // 源文本

          cv::Scalar color(0, 255, 0); // 绿色

          // 2. 计算目标高度对应的字体缩放比例

          double fontScale = cv::getFontScaleFromHeight(fontFace, targetHeight, thickness);

          std::cout << "Calculated Font Scale: " << fontScale << std::endl;

          // 3. 以计算出的缩放比例渲染文本

          cv::putText(image, text, org, fontFace, fontScale, color, thickness);

          // 4. 验证高度(可选)

          int baseLine = 0;

          cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseLine);

          std::cout << "Actual Text Height: " << textSize.height << "px" << std::endl;

          cv::imshow("Font Height Example", image);

          cv::waitKey(0);

          return 0;

}

运行结果:

3.11 getTextSize

int Test_getTextSize()

{

          // 1. Create a black image

          cv::Mat img = cv::Mat::zeros(400, 600, CV_8UC3);

          // 2. 定义文本属性

          std::string text = "Hello OpenCV!";

          int fontFace = cv::FONT_HERSHEY_SIMPLEX;

          double fontScale = 1.5;

          int thickness = 2;

          int baseline = 0;

          // 3. 计算文本大小

          cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);

          // 4. 计算文本中心的位置

          // Center point (x) = (ImageWidth - TextWidth) / 2

          // Center point (y) = (ImageHeight + TextHeight) / 2

          cv::Point textOrg((img.cols - textSize.width) / 2,

                    (img.rows + textSize.height) / 2);

          // 5. 绘制文本及外围框(可选)

          cv::putText(img, text, textOrg, fontFace, fontScale, cv::Scalar(0, 255, 0), thickness);

          // 绘制可视化基线

          cv::line(img, textOrg + cv::Point(0, thickness),

                    textOrg + cv::Point(textSize.width, thickness), cv::Scalar(0, 0, 255));

          cv::imshow("Centered Text", img);

          cv::waitKey(0);

          return 0;

}

运行结果:

3.12 line

int Test_line()

{

          // 1. Create a black image (512x512 pixels, 3-channel BGR)

          cv::Mat image = cv::Mat::zeros(512, 512, CV_8UC3);

          // 2. Define start and end points

          cv::Point start(0, 0);

          cv::Point end(511, 511);

          // 3. Draw the line

          // Parameters: (image, start, end, color, thickness, lineType)

          cv::line(image, start, end, cv::Scalar(0, 255, 0), 3, cv::LINE_AA);

          // 4. Display the result

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

          cv::waitKey(0); // Wait for a key press

          return 0;

}

运行结果:

3.13 polylines

int Test_polylines()

{

          // 1. Create a black image (512x512 pixels, 3 color channels)

          cv::Mat image = cv::Mat::zeros(512, 512, CV_8UC3);

          // 2. Define the vertices of the polygon

          std::vector<cv::Point> pts;

          pts.push_back(cv::Point(250, 100));

          pts.push_back(cv::Point(400, 400));

          pts.push_back(cv::Point(100, 400));

          // 3. polylines expects an InputArrayOfArrays (a vector of vectors)

          std::vector<std::vector<cv::Point>> polylines_pts;

          polylines_pts.push_back(pts);

          // 4. Draw the polyline

          // Parameters: image, points, isClosed=true, color=Green(0,255,0), thickness=3

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

          // 5. Display the result

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

          cv::waitKey(0);

          return 0;

}

运行结果:

3.14 putText

int Test_putText()

{

          // Create a 512x512 black image (3 channels)

          cv::Mat img = cv::Mat::zeros(256, 512, CV_8UC3);

          // Text properties

          std::string text = "Hello, OpenCV!";

          cv::Point position(50, 125); // Bottom-left corner of the text

          int fontFace = cv::FONT_HERSHEY_SIMPLEX;

          double fontScale = 2.0;

          cv::Scalar color(0, 0, 255); // Blue in BGR

          int thickness = 2;

          // Write text on the image

          cv::putText(img, text, position, fontFace, fontScale, color, thickness, cv::LINE_AA);

          // Display the result

          cv::imshow("Text Example", img);

          cv::waitKey(0);

          return 0;

}

运行结果:

3.15 rectangle

int Test_rectangle()

{

          // 1. Create a black image (512x512 pixels, 3 color channels)

          cv::Mat image = cv::Mat::zeros(512, 512, CV_8UC3);

          // 2. Define rectangle using two points (Top-Left and Bottom-Right)

          // Draws a green rectangle with a thickness of 3 pixels

          cv::Point pt1(100, 100);

          cv::Point pt2(400, 200);

          cv::rectangle(image, pt1, pt2, cv::Scalar(0, 255, 0), 3);

          // 3. Define rectangle using cv::Rect(x, y, width, height)

          // Draws a filled red rectangle (thickness = -1 or FILLED)

          cv::Rect myRect(50, 300, 150, 100);

          cv::rectangle(image, myRect, cv::Scalar(0, 0, 255), cv::FILLED);

          // 4. Display the result

          cv::imshow("OpenCV Rectangle Example", image);

          cv::waitKey(0); // Wait for a key press

          return 0;

}

运行结果:

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐