#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 ); // 如果不画箭头, 绘制线条elsearrowedLine(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,则画一个矩形elsedrawMarker(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