【opencv】示例-drawing.cpp画线、箭头、矩形、多边形、椭圆、圆形以及在图像上渲染文本并通过循环实现动态绘制效果...

e3a523c0ced20cf4f4fc14b5c2b812ed.png

#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函数,如linearrowedLinerectanglepolylinesfillPolycircleputText等。主要功能是展示OpenCV在图像处理中绘制图形和输出文本的能力。

01f6a099f77bd92026ab947f9e45800d.png

f33cff93e2705d3be8e42ebefdcfd9a3.png

line、arrowedLine、rectangle、polylines、fillPoly、circle和putText

66d6f54a041fa5bd66641bfe7df3aa02.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/529904.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智慧工厂如何利用ARM运算平台实现边缘智能控制

AI边缘智能控制成为了推动智慧工厂等领域革新的关键力量。在这个变革的浪潮中&#xff0c;ARM运算平台以其高效能、低功耗的特性&#xff0c;为AI边缘智能控制提供了坚实的硬件基础。通过ARM运算平台&#xff0c;智能设备能够在边缘端实时处理数据&#xff0c;避免了数据传输的…

[Kubernetes集群:master主节点初始化]:通过Calico和Coredns网络插件方式安装

文章目录 前置&#xff1a;Docker和K8S安装版本匹配查看0.1&#xff1a;安装指定docker版本 **[1 — 7] ** [ 配置K8S主从集群前置准备操作 ]一&#xff1a;主节点操作 查看主机域名->编辑域名->域名配置二&#xff1a;安装自动填充&#xff0c;虚拟机默认没有三&#xf…

如何在前后端一体的项目中引入element-ui,即引入index.js、index.css等文件。

24年接手了一个18年的项目&#xff0c;想使用el-ui的组件库&#xff0c;得自己手动引入。 通过官网可以知道&#xff0c;首先得准备以下文件 <!-- 引入样式 --> <link rel"stylesheet" href"https://unpkg.com/element-ui/lib/theme-chalk/index.css…

目标检测——YOLO系列学习(一)YOLOv1

YOLO可以说是单阶段的目标检测方法的集大成之作&#xff0c;必学的经典论文&#xff0c;从准备面试的角度来学习一下yolo系列。 YOLOv1 1.RCNN系列回顾 RCNN系列&#xff0c;无论哪种算法&#xff0c;核心思路都是Region Proposal&#xff08;定位&#xff09; classifier&am…

Redis中的集群(三)

集群 槽指派 记录节点的槽指派信息。 clusterNode结构的slots属性和numslot属性记录了节点负责处理哪些槽: struct clusterNode { // ... unsigned char slots[16384/8];int numslots; // ... }slots属性是一个二进制位数组(bit array)&#xff0c;这个数组的长度位16384/8…

XILINX 7系列时钟资源

文章目录 前言一、时钟概要1.1、CC1.2、BUFR、BUFIO、BUFMR1.3、CMT1.4、BUFH1.5、BUFG 二、时钟路由资源三、CMT 前言 本文主要参考xilinx手册ug472 一、时钟概要 7系列FPGA时钟资源主要有CC、BUFR、BUFIO、BUFMR、CMT、BUFG、BUFH和GTE_COMMON 1.1、CC “CC”&#xff0…

Word 画三线表模板---一键套用

1、制作三线表 1&#xff09;设置为无边框 选中表格&#xff0c;点击「右键」——「边框」——「无框线」。 2&#xff09;添加上下边框线 选中表格后&#xff0c;点击【右键】——【表格属性】——【边框和底纹】&#xff0c;边框线选择【1.5磅】&#xff0c;然后点击【上框…

申请GeoTrust证书

GeoTrust是全球知名的数字证书颁发机构&#xff08;CA&#xff09;和安全解决方案提供商。它成立于1999年&#xff0c;后来成为DigiCert旗下的一部分。GeoTrust专注于提供SSL证书和其他安全产品&#xff0c;以保护网站流量、电子邮件通信和企业身份的安全。 GeoTrust的SSL证书在…

一文掌握RabbitMQ核心概念和原理

本文主要通过图文的方式介绍了RabbitMQ核心概念和原理&#xff0c;包括工作模型、交换机类型、交换机和队列的详细属性、过期消息、死信队列、延迟队列、消息可靠性和幂等性、集群分类等方面。 文章目录 消息中间件概念应用场景 RabbitMQ工作模型和基本概念RabbitMQ交换机类型交…

GitHub 仓库 (repository) Pulse - Contributors - Network

GitHub 仓库 [repository] Pulse - Contributors - Network 1. Pulse2. Contributors3. NetworkReferences 1. Pulse 显示该仓库最近的活动信息。该仓库中的软件是无人问津&#xff0c;还是在火热地开发之中&#xff0c;从这里可以一目了然。 2. Contributors 显示对该仓库进…

【数据结构】考研真题攻克与重点知识点剖析 - 第 7 篇:查找

前言 本文基础知识部分来自于b站&#xff1a;分享笔记的好人儿的思维导图与王道考研课程&#xff0c;感谢大佬的开源精神&#xff0c;习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析&#xff0c;本人技术…

微信小程序Skyline模式下瀑布长列表优化成虚拟列表,解决内存问题

微信小程序长列表&#xff0c;渲染的越多就会导致内存吃的越多。特别是长列表的图片组件和广告组件。 为了解决内存问题&#xff0c;所以看了很多人的资料&#xff0c;都不太符合通用的解决方式&#xff0c;很多需要固定子组件高度&#xff0c;但是瀑布流是无法固定的&#xf…

STM32H7通用定时器计数功能的使用

目录 概述 1 STM32定时器介绍 1.1 认识通用定时器 1.2 通用定时器的特征 1.3 递增计数模式 1.4 时钟选择 2 STM32Cube配置定时器时钟 2.1 配置定时器参数 2.2 配置定时器时钟 3 STM32H7定时器使用 3.1 认识定时器的数据结构 3.2 计数功能实现 4 测试案例 4.1 代码…

三极管结构难?——秒了

前边我们已经学完了PN结&#xff0c;二极管&#xff0c;在分析了二极管后&#xff0c;我们对这些东西有了一定深度的了解&#xff0c;但是只给我们一个二极管去研究&#xff0c;这玩意好像真的没啥大用&#xff0c;其实我们追求的是用半导体材料去代替电子管的放大作用&#xf…

0.开篇:SSM+Spring Boot导学

1. 为什么要使用框架 Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。 几乎当下所有企业级JavaEE开发都离不开SSM&#xff08;Spring SpringMVC MyBatis&#xff09;Spring B…

c/c++ |游戏后端开发之skynet

作者眼中的skynet 有一点要说明的是&#xff0c;云风至始也没有公开说skynet专门为游戏开发&#xff0c;换句话&#xff0c;skynet 引擎也可以用于web 开发 贴贴我的笔记 skynet 核心解决什么问题 愿景&#xff1a;游戏服务器能够充分利用多核优势&#xff0c;将不同的业务放在…

Visual Studio Code 终端为管理员权限

第一部 1、 Visual Studio Code 快捷方式启动选项加上管理员启动 第二步 管理员方式运行 powershell Windows 10的任务栏自带了搜索。或者开始菜单选搜索只需在搜索框中输入powershell。 在出来的搜索结果中右击Windows PowerShell&#xff0c;然后选择以管理员方式运行。 执…

Apache Doris 基于 Job Scheduler 实现秒级触发任务调度能力

作者&#xff5c;SelectDB 技术团队 在数据管理愈加精细化的需求背景下&#xff0c;定时调度在其中扮演着重要的角色。它通常被应用于以下场景&#xff1a; 定期数据更新&#xff0c;如周期性数据导入和 ETL 操作&#xff0c;减少人工干预&#xff0c;提高数据处理的效率和准…

Java基于微信小程序的校园外卖平台设计与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

03-JAVA设计模式-代理模式详解

代理模式 什么是代理模式 Java代理模式是一种常用的设计模式&#xff0c;主要用于在不修改现有类代码的情况下&#xff0c;为该类添加一些新的功能或行为。代理模式涉及到一个代理类和一个被代理类&#xff08;也称为目标对象&#xff09;。代理类负责控制对目标对象的访问&a…