#include "opencv2/core.hpp" // 引入opencv2核心头文件
#include "opencv2/imgproc.hpp" // 引入opencv2图像处理头文件
#include "opencv2/highgui.hpp" // 引入opencv2高级GUI(head-up display)头文件
#include <stdio.h> // 引入标准输入输出头文件
using namespace cv; // 使用cv命名空间
// 帮助函数,用于打印程序说明
static void help(char** argv)
{
printf("\nThis program demonstrates OpenCV drawing and text output functions.\n"
"Usage:\n"
" %s\n", argv[0]);
}
// 函数生成随机颜色,用于绘图
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng; // 生成随机数作为颜色值
return Scalar(icolor&255, (icolor>>8)&255, (icolor>>16)&255); // 返回一个Scalar, 表示BGR颜色
}
// 主函数
int main(int /* argc */, char** argv) // main函数,笔误argv用于命令行参数
{
help(argv); // 调用help函数显示帮助
char wndname[] = "Drawing Demo"; // 窗口名
const int NUMBER = 100; // 定义数量常量
const int DELAY = 5; // 定义延时常量
int lineType = LINE_AA; // 定义线类型为抗锯齿线条,可以改为LINE_8查看非抗锯齿效果
int i, width = 1000, height = 700; // 定义循环变量i以及窗口宽高
int x1 = -width/2, x2 = width*3/2, y1 = -height/2, y2 = height*3/2; // 定义坐标范围
RNG rng(0xFFFFFFFF); // 创建随机数生成器
Mat image = Mat::zeros(height, width, CV_8UC3); // 创建一个黑色图像
imshow(wndname, image); // 显示图像
waitKey(DELAY); // 等待键盘输入
// 绘制随机线条和箭头
for (i = 0; i < NUMBER * 2; i++)
{
Point pt1, pt2; // 定义两点
pt1.x = rng.uniform(x1, x2); // 随机生成第一个点的x坐标
pt1.y = rng.uniform(y1, y2); // 随机生成第一个点的y坐标
pt2.x = rng.uniform(x1, x2); // 随机生成第二个点的x坐标
pt2.y = rng.uniform(y1, y2); // 随机生成第二个点的y坐标
int arrowed = rng.uniform(0, 6); // 随机决定是否画箭头
if( arrowed < 3 )
line( image, pt1, pt2, randomColor(rng), rng.uniform(1,10), lineType ); // 如果不画箭头, 绘制线条
else
arrowedLine(image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), lineType); // 如果画箭头, 绘制箭头线条
imshow(wndname, image); // 显示图像
if(waitKey(DELAY) >= 0) // 如果按下任意键,则退出
return 0;
}
// 绘制随机矩形和标记
for (i = 0; i < NUMBER * 2; i++)
{
Point pt1, pt2; // 定义矩形对角线上的两个点
pt1.x = rng.uniform(x1, x2); // 随机生成点pt1的x坐标
pt1.y = rng.uniform(y1, y2); // 随机生成点pt1的y坐标
pt2.x = rng.uniform(x1, x2); // 随机生成点pt2的x坐标
pt2.y = rng.uniform(y1, y2); // 随机生成点pt2的y坐标
int thickness = rng.uniform(-3, 10); // 随机生成线条宽度
int marker = rng.uniform(0, 10); // 随机决定绘制的形状是矩形还是标记
int marker_size = rng.uniform(30, 80); // 随机生成标记的大小
if (marker > 5)
rectangle(image, pt1, pt2, randomColor(rng), MAX(thickness, -1), lineType); // 如果marker大于5,则画一个矩形
else
drawMarker(image, pt1, randomColor(rng), marker, marker_size ); // 如果marker小于或等于5,则绘制一个标记
imshow(wndname, image); // 显示图像
if(waitKey(DELAY) >= 0) // 如果在DELAY时间内收到按键,结束程序
return 0;
}
// 绘制椭圆
for (i = 0; i < NUMBER; i++)
{
Point center; // 定义椭圆中心点
center.x = rng.uniform(x1, x2); // 随机生成中心点的x坐标
center.y = rng.uniform(y1, y2); // 随机生成中心点的y坐标
Size axes; // 定义椭圆的长轴和短轴
axes.width = rng.uniform(0, 200); // 随机生成长轴的长度
axes.height = rng.uniform(0, 200); // 随机生成短轴的长度
double angle = rng.uniform(0, 180); // 随机生成椭圆的旋转角度
ellipse( image, center, axes, angle, angle - 100, angle + 200,
randomColor(rng), rng.uniform(-1,9), lineType ); // 画椭圆
imshow(wndname, image); // 显示图像
if(waitKey(DELAY) >= 0) // 如果在DELAY时间内收到按键,结束程序
return 0;
}
// 绘制多边形线条
for (i = 0; i< NUMBER; i++)
{
Point pt[2][3]; // 定义多边形的顶点数组
// 下面的部分是随机生成两个三角形的顶点
pt[0][0].x = rng.uniform(x1, x2);
pt[0][0].y = rng.uniform(y1, y2);
pt[0][1].x = rng.uniform(x1, x2);
pt[0][1].y = rng.uniform(y1, y2);
pt[0][2].x = rng.uniform(x1, x2);
pt[0][2].y = rng.uniform(y1, y2);
pt[1][0].x = rng.uniform(x1, x2);
pt[1][0].y = rng.uniform(y1, y2);
pt[1][1].x = rng.uniform(x1, x2);
pt[1][1].y = rng.uniform(y1, y2);
pt[1][2].x = rng.uniform(x1, x2);
pt[1][2].y = rng.uniform(y1, y2);
const Point* ppt[2] = {pt[0], pt[1]}; // 创建指向顶点数组的指针数组
int npt[] = {3, 3}; // 创建顶点数量数组
polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1,10), lineType); // 绘制多边形的轮廓
imshow(wndname, image); // 显示图像
if(waitKey(DELAY) >= 0) // 如果在DELAY时间内收到按键,结束程序
return 0;
}
// 填充多边形
for (i = 0; i< NUMBER; i++)
{
Point pt[2][3]; // 定义多边形的顶点数组
// 下面的部分是随机生成两个三角形的顶点
pt[0][0].x = rng.uniform(x1, x2);
pt[0][0].y = rng.uniform(y1, y2);
pt[0][1].x = rng.uniform(x1, x2);
pt[0][1].y = rng.uniform(y1, y2);
pt[0][2].x = rng.uniform(x1, x2);
pt[0][2].y = rng.uniform(y1, y2);
pt[1][0].x = rng.uniform(x1, x2);
pt[1][0].y = rng.uniform(y1, y2);
pt[1][1].x = rng.uniform(x1, x2);
pt[1][1].y = rng.uniform(y1, y2);
pt[1][2].x = rng.uniform(x1, x2);
pt[1][2].y = rng.uniform(y1, y2);
const Point* ppt[2] = {pt[0], pt[1]}; // 创建指向顶点数组的指针数组
int npt[] = {3, 3}; // 创建顶点数量数组
fillPoly(image, ppt, npt, 2, randomColor(rng), lineType); // 填充多边形
imshow(wndname, image); // 显示图像
if(waitKey(DELAY) >= 0) // 如果在DELAY时间内收到按键,结束程序
return 0;
}
// 绘制圆形
for (i = 0; i < NUMBER; i++)
{
Point center; // 定义圆心
center.x = rng.uniform(x1, x2); // 随机生成圆心的x坐标
center.y = rng.uniform(y1, y2); // 随机生成圆心的y坐标
circle(image, center, rng.uniform(0, 300), randomColor(rng),
rng.uniform(-1, 9), lineType); // 画圆
imshow(wndname, image); // 显示图像
if(waitKey(DELAY) >= 0) // 如果在DELAY时间内收到按键,结束程序
return 0;
}
// 在图像上绘制文字
for (i = 1; i < NUMBER; i++)
{
Point org; // 定义文字显示的位置
org.x = rng.uniform(x1, x2); // 随机生成位置的x坐标
org.y = rng.uniform(y1, y2); // 随机生成位置的y坐标
putText(image, "Testing text rendering", org, rng.uniform(0,8),
rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType); // 在图像上放置文字
imshow(wndname, image); // 显示图像
if(waitKey(DELAY) >= 0) // 如果在DELAY时间内收到按键,结束程序
return 0;
}
// 绘制渐变文字“OpenCV forever!”
Size textsize = getTextSize("OpenCV forever!", FONT_HERSHEY_COMPLEX, 3, 5, 0); // 获取文字尺寸
Point org((width - textsize.width)/2, (height - textsize.height)/2); // 计算文字位置
Mat image2; // 创建另一个图像
for( i = 0; i < 255; i += 2 ) // 用循环绘制渐变效果
{
image2 = image - Scalar::all(i); // 使图像变暗
putText(image2, "OpenCV forever!", org, FONT_HERSHEY_COMPLEX, 3,
Scalar(i, i, 255), 5, lineType); // 绘制渐变文字
imshow(wndname, image2); // 显示文字效果
if(waitKey(DELAY) >= 0) // 如果按下任意键,则退出
return 0;
}
waitKey(); // 等待键盘输入
return 0; // 正常退出
}
此段代码是一段利用OpenCV库绘制各种图形和文字的C++示例程序。程序包括了画线、箭头、矩形、多边形、椭圆、圆形以及在图像上渲染文本,并通过循环实现动态绘制效果。使用了多种OpenCV函数,如line
、arrowedLine
、rectangle
、polylines
、fillPoly
、circle
和putText
等。主要功能是展示OpenCV在图像处理中绘制图形和输出文本的能力。
line、arrowedLine、rectangle、polylines、fillPoly、circle和putText