目录
[2.1. 直线:cv::line()](#2.1. 直线:cv::line())
[2.2. 矩形:cv::rectangle()](#2.2. 矩形:cv::rectangle())
[2.3. 圆形:cv::circle()](#2.3. 圆形:cv::circle())
[2.4. 椭圆:cv::ellipse()](#2.4. 椭圆:cv::ellipse())
[2.5. 多边形:cv::polylines() / cv::fillPoly()](#2.5. 多边形:cv::polylines() / cv::fillPoly())
[2.6. 文本:cv::putText()](#2.6. 文本:cv::putText())
[2.7 绘制通用参数](#2.7 绘制通用参数)
[2.8 一些常见应用场景](#2.8 一些常见应用场景)
[2.8.1. 目标检测 / 识别可视化](#2.8.1. 目标检测 / 识别可视化)
[2.8.2. 图像处理调试](#2.8.2. 图像处理调试)
[2.8.3. 信息展示](#2.8.3. 信息展示)
一、基本概念
OpenCV 提供了一套轻量级、高效的 2D 图形绘制 API ,。这些函数是计算机视觉可视化、调试、标注的基础工具,几乎所有视觉项目都会用到其核心函数如下:
| 图形类型 | 函数 | 核心作用 |
|---|---|---|
| 直线 | cv::line() |
绘制两点之间的线段 |
| 矩形 | cv::rectangle() |
绘制矩形框(可填充) |
| 圆形 | cv::circle() |
绘制圆形(可填充) |
| 椭圆 | cv::ellipse() |
绘制椭圆 / 圆弧 |
| 多边形 | cv::polylines() / cv::fillPoly() |
绘制 / 填充多边形 |
| 文本 | cv::putText() |
在图像上绘制文字 |
| 箭头 | cv::arrowedLine() |
绘制带箭头的线段 |
二、绘制函数详解
2.1. 直线:cv::line()
void cv::line(
InputOutputArray img, // 要绘制的图像(会被修改)
Point pt1, // 起点坐标 (x,y)
Point pt2, // 终点坐标 (x,y)
const Scalar& color, // 颜色(BGR 格式,如 Scalar(0,0,255) 红色)
int thickness = 1, // 线条宽度(-1 表示填充,仅对封闭图形有效)
int lineType = LINE_8, // 线条类型:LINE_4(4邻接)、LINE_8(8邻接)、LINE_AA(抗锯齿)
int shift = 0 // 坐标点的小数位数(一般用0)
);
lineType说明 :LINE_4/LINE_8:像素连接方式,LINE_8更平滑;LINE_AA:抗锯齿,线条更柔和,但绘制稍慢。
2.2. 矩形:cv::rectangle()
cpp
void cv::rectangle(
InputOutputArray img,
Rect rect, // 矩形区域 Rect(x,y,w,h)
const Scalar& color,
int thickness = 1, // thickness=-1 时填充矩形
int lineType = LINE_8,
int shift = 0
);
// 或传入两点:
void cv::rectangle(
InputOutputArray img,
Point pt1, Point pt2, // 对角两点
const Scalar& color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
);
2.3. 圆形:cv::circle()
cpp
void cv::circle(
InputOutputArray img,
Point center, // 圆心坐标
int radius, // 半径
const Scalar& color,
int thickness = 1, // thickness=-1 时填充圆形
int lineType = LINE_8,
int shift = 0
);
2.4. 椭圆:cv::ellipse()
cpp
void cv::ellipse(
InputOutputArray img,
Point center, // 椭圆中心
Size axes, // 半长轴、半短轴 (w,h)
double angle, // 椭圆旋转角度(度)
double startAngle, // 起始角度
double endAngle, // 结束角度(0~360 为完整椭圆)
const Scalar& color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
);
2.5. 多边形:cv::polylines() / cv::fillPoly()
cpp
// 绘制多边形轮廓
void cv::polylines(
InputOutputArray img,
const Point* pts, // 多边形顶点数组
int npts, // 顶点数量
bool isClosed, // 是否闭合(true 则首尾连接)
const Scalar& color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
);
// 填充多边形
void cv::fillPoly(
InputOutputArray img,
const Point* pts,
int npts,
const Scalar& color,
int lineType = LINE_8,
int shift = 0
);
//填充多边形 可以一次绘制多个多边形
void cv::fillPoly(
InputOutputArray img, // 绘制图像
const Point** pts, // 【二维指针】多个多边形的顶点数组(每个元素是一个多边形的顶点指针)
const int* npts, // 【数组】每个多边形对应的顶点数(如 [3,4,5] 表示3个多边形分别有3/4/5个顶点)
int ncontours, // 要绘制的多边形总数(如3)
const Scalar& color, // 填充颜色(所有多边形同色)
int lineType = LINE_8,
int shift = 0,
Point offset = Point() // 可选:所有多边形整体偏移
);
2.6. 文本:cv::putText()
cpp
void cv::putText(
InputOutputArray img,
const String& text, // 要绘制的文字
Point org, // 文字左下角坐标
int fontFace, // 字体(如 FONT_HERSHEY_SIMPLEX)
double fontScale, // 字体缩放比例
Scalar color,
int thickness = 1,
int lineType = LINE_8,
bool bottomLeftOrigin = false // 坐标是否为左下角
);
- 常用字体:
FONT_HERSHEY_SIMPLEX(简洁无衬线)、FONT_HERSHEY_COMPLEX(复杂衬线)。
2.7 绘制通用参数
| 参数 | 含义 | 典型取值 |
|---|---|---|
img |
输入输出图像(会被直接修改 ,建议先 clone() 再绘制) |
Mat img = imread("test.jpg"); Mat drawImg = img.clone(); |
color |
颜色(BGR 顺序) | 红色:Scalar(0,0,255),绿色:Scalar(0,255,0),蓝色:Scalar(255,0,0),白色:Scalar(255,255,255) |
thickness |
线条宽度 | 正数:轮廓宽度;-1:填充图形(仅对矩形 / 圆形 / 椭圆 / 多边形有效) |
lineType |
线条渲染类型 | LINE_8(默认,速度快)、LINE_AA(抗锯齿,更平滑) |
shift |
坐标小数位数 | 一般为 0(整数坐标),高精度场景可设为 1~4 |
2.8 一些常见应用场景
2.8.1. 目标检测 / 识别可视化
- 场景:在图像上框出检测到的物体(人脸、车辆、文字等),标注类别和置信度。
- 用到的函数 :
rectangle():绘制目标框;putText():标注类别名称(如 "face 0.98");circle():标记关键点(如人脸关键点)。
- 如YOLO/Faster R-CNN 等检测算法的结果可视化。
2.8.2. 图像处理调试
- 场景:在图像上标记特征点、轮廓、ROI 区域,方便调试算法。
- 用到的函数 :
line():连接特征点,绘制轮廓;circle():标记角点 / 特征点;rectangle():框出 ROI 区域。
2.8.3. 信息展示
- 场景:在图像上叠加提示信息、时间戳、状态文字。
- 用到的函数 :
putText()+rectangle()(绘制背景框提升文字可读性)。
三、绘制函数使用举例
cpp
void testDraw()
{
Mat img = Mat(Size(512, 512), CV_8UC3,Scalar(255,255,255));//白板
//绘制圆形
circle(img, Point(50, 50), 25, Scalar(0, 0, 255), -1);
circle(img, Point(100, 50), 20, Scalar(0, 255, 0), 4);
//绘制直线
line(img, Point(100, 100), Point(200, 150), Scalar(255, 0, 0), 2, LINE_4, 0);
line(img, Point(100, 120), Point(200, 170), Scalar(255, 0, 0), 2, LINE_8, 0);
//绘制椭圆
ellipse(img, Point(100, 255), Size(100, 70), 0,0, 360, Scalar(255, 0, 0), -1);
ellipse(img, Point(100, 255), Size(100, 70), 0, 0, 360, Scalar(0, 255, 0), 4);
//绘制矩形
rectangle(img, Point(50, 400), Point(150, 500), Scalar(125, 125, 125), -1);
//绘制多边形 填充
Point PointsSet[3][5] = { { Point(220, 100),Point(220, 120),Point(330, 130),Point(440, 160) ,Point(380, 120) } ,
{ Point(220, 300),Point(220, 180),Point(300, 170),Point(320, 200) ,Point(300, 200) },
{ Point(280, 250),Point(300, 290),Point(500, 300),Point(440, 200) ,Point(400, 180) } };
int npts[3] = { 5,5,5 };
const Point *Set[3] = { PointsSet[0],PointsSet[1],PointsSet[2]};
fillPoly(img, Set, npts, 3, Scalar(125, 125, 125),LINE_8);
polylines(img, Set, npts, 3,true, Scalar(0, 0, 255),4);
//生成文字
putText(img, "Good Good Study Day Day Up", Point(10, 350), 2, 1, Scalar(0, 0, 255),2);
imshow("draw", img);
waitKey();
}
