实战OpenCV之绘制图形

news2024/9/21 21:08:46

基础入门

        OpenCV除了用于图像显示之外,还提供了一系列接口和工具,以帮助开发者在图像上绘制各种图形。这里的图形包括:直线、矩形、圆形、椭圆、多边形等。另外,OpenCV还支持在图像上添加文字,对多张图像进行叠加操作。

        下面,我们将逐一介绍OpenCV中与绘制图形相关的API接口。

        1、绘制直线。使用cv::line()函数,其声明如下。

void line(InputOutputArray img, Point pt1, Point pt2, 
    const Scalar& color, int thickness=1, int lineType=8, int shift=0);

        各个参数的含义如下。

        img:输入输出图像的数组。

        pt1:直线的起点坐标。

        pt2:直线的终点坐标。

        color:直线颜色。

        thickness:线宽。

        lineType:线条类型,如8连接线、抗锯齿线等。

        shift:坐标点分量的位移量。

        2、绘制矩形。使用cv::rectangle()函数,其声明如下。

void rectangle(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, 
    int thickness=1, int lineType=8, int shift=0);

        各个参数的含义如下。

        img:输入输出图像的数组。

        pt1:矩形的左上角坐标。

        pt2:矩形的右下角坐标。

        color: 边框颜色。

        thickness:边框厚度,若为负值则填充矩形内部。

        lineType:同上。

        shift:同上。

        3、绘制圆形。使用cv::circle()函数,其声明如下。

void circle(InputOutputArray img, Point center, int radius, const Scalar& color, 
    int thickness=1, int lineType=8, int shift=0);

        各个参数的含义如下。

        img:输入输出图像的数组。

        center:圆心坐标。

        radius:圆半径。

        color: 圆边框颜色。

        thickness:边框厚度,若为负值则填充圆内部。

        lineType:同上。

        shift:同上。

        4、绘制椭圆。使用cv::ellipse()函数,其声明如下。

void ellipse(InputOutputArray img, Point center, Size axes, double angle, 
    double startAngle, double endAngle, const Scalar& color, int thickness=1, 
    int lineType=8, int shift=0);

        各个参数的含义如下。

        img:输入输出图像数组。

        center:椭圆中心坐标。

        axes:半轴长度,长轴和短轴。

        angle:长轴与水平方向的夹角(以度为单位)。

        startAngle:开始角度。

        endAngle:结束角度。

        color:椭圆颜色。

        thickness:边框厚度,若为负值则填充椭圆内部。

        lineType:同上。

        shift:同上。

        5、绘制多边形。使用cv::polylines()函数,其声明如下。

void polylines(InputOutputArray img, InputArrayOfArrays pts, bool isClosed, 
    const Scalar& color, int thickness=1, int lineType=8, int shift=0);

        各个参数的含义如下。

        img:输入输出图像数组。

        pts:多边形顶点的坐标集。

        isClosed:是否闭合多边形。

        color:边框颜色。

        thickness:边框厚度,若为负值则填充多边形内部。

        lineType:同上。

        shift:同上。

        6、填充多边形。使用cv::fillPoly()函数,其声明如下。

void fillPoly(InputOutputArray img, InputArrayOfArrays pts, const Scalar& color, 
    int lineType=8, int shift=0, int offset=Point());

        各个参数的含义如下。

        img:输入输出图像数组。

        pts:多边形顶点的坐标集。

        color:填充颜色。

        lineType:同上。

        shift:同上。

        offset:坐标的偏移量。

实战解析

        下面的实战代码使用上述基本绘图函数创建了一个包含多种图形的图像,我们可以通过调整参数来改变这些图形的颜色、位置、大小和其他属性。

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;

int main()
{
    // 创建一个512 x 512的白色背景图像
    Mat image(512, 512, CV_8UC3, Scalar(255, 255, 255));

    // 绘制绿色的直线
    line(image, Point(0, 0), Point(511, 511), Scalar(0, 255, 0), 5);

    // 绘制红色的矩形
    rectangle(image, Point(384, 0), Point(510, 128), Scalar(0, 0, 255), 3);

    // 绘制红色的实心圆
    circle(image, Point(447, 63), 63, Scalar(0, 0, 255), -1);

    // 绘制蓝色的椭圆
    ellipse(image, Point(226, 226), Size(100, 50), 0, 0, 180, Scalar(255, 0, 0), 2);

    // 绘制多边形
    vector<Point> polygon;
    polygon.push_back(Point(200, 100));
    polygon.push_back(Point(250, 100));
    polygon.push_back(Point(225, 200));
    polylines(image, polygon, true, Scalar(255, 255, 0));

    // 显示图像
    imshow("Draw Shapes Mode 0", image);
    
    cv::waitKey(0);
    destroyAllWindows();
    return 0;
}

        执行上面的示例代码,运行效果可参考下图。

添加文字

        有时候,我们希望在图像上添加文字或标注,以增强图像的可读性和信息量。此时,可以使用putText函数。

        putText函数的原型如下。

void putText(
    InputOutputArray img,          // 输入输出图像
    const String& text,            // 要显示的文本字符串
    Point org,                     // 文本起始位置(左下角或左上角)
    int fontFace,                  // 字体样式
    double fontScale,              // 字体缩放因子
    const Scalar& color,           // 文本颜色
    int thickness = 1,             // 文本线条厚度
    int lineType = LINE_8,         // 线条类型
    bool bottomLeftOrigin = true   // 是否以左下角为原点
)

        在下面的实战代码中,我们使用putText()函数在图像上添加了蓝色文本"Hello, Hope_Wisdom"。文本的起始位置为(50, 50),字体为cv::FONT_HERSHEY_SIMPLEX,字体大小为1,颜色为蓝色,线条厚度为2。

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;

int main()
{
    // 读取图像,请替换为你自己的图片路径
    Mat image = imread("OpenCV.png");

    // 检查图像是否被正确读取
    if(image.empty())
    {
        cout << "Can not open or find the image" << endl;
        return -1;
    }

    // 创建一个名为"Draw Shapes Mode 1"的窗口,WINDOW_NORMAL允许调整窗口大小
    namedWindow("Draw Shapes Mode 1", WINDOW_NORMAL);
    // image.cols代表图像的宽度, image.rows代表图像的高度
    resizeWindow("Draw Shapes Mode 1", image.cols, image.rows);
    // 添加蓝色的文本
    putText(image, "Hello, Hope_Wisdom", Point(50, 50), 
        FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 0, 0), 2);
    // 在窗口中显示图像
    imshow("Draw Shapes Mode 1", image);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

        执行上面的示例代码,运行效果可参考下图。

图像叠加

        在处理多图像时,我们有时候需要在同一窗口中叠加显示多张图像,这可以通过图像融合来实现。addWeighted函数能够根据给定的权重将两个图像的像素值线性组合,同时还可以添加一个亮度补偿项,以控制最终图像的亮度。注意,使用此函数前,需要确保两个输入图像具有相同的尺寸和通道数,否则需要先进行调整。

        addWeighted函数的原型如下。

Mat addWeighted(
    const cv::Mat& src1,      // 第一个输入数组
    double alpha,             // 第一个输入数组的权重
    const cv::Mat& src2,      // 第二个输入数组
    double beta,              // 第二个输入数组的权重
    double gamma,             // 加到和上的标量
    cv::Mat& dst,             // 输出数组
    int ddepth = -1           // 可选,输出图像深度;如果设置为负数,则与输入图像深度相同
)

        在下面的实战代码中,我们首先读取了两张图像。如果两张图像的尺寸不一致,我们会使用resize函数来进行调整,以满足addWeighted函数的要求。最后,我们将两张图像以50%的透明度进行了叠加,并将融合后的图像显示出来。

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;

int main()
{
    // 读取图像,请替换为你自己的图片路径
    Mat image1 = imread("OpenCV.png");
    Mat image2 = imread("C++.png");

    // 检查图像是否被正确读取
    if(image1.empty() || image2.empty())
    {
        cout << "Can not open or find the image" << endl;
        return -1;
    }

    // 获取两张图片的尺寸
    Size size1 = image1.size();
    Size size2 = image2.size();

    // 确定目标尺寸,这里以较大尺寸为准
    Size targetSize = size1.area() > size2.area() ? size1 : size2;
    // 如果尺寸不一致,调整图片大小
    if (size1 != targetSize)
    {
        resize(image1, image1, targetSize);
    }
    else if (size2 != targetSize)
    {
        resize(image2, image2, targetSize);
    }
    else
    {
        NULL;
    }

    // 创建一个空的Mat对象来存放结果
    Mat result;
    double alpha = 0.5; // 图像1的透明度
    double beta = 0.5;  // 图像2的透明度
    double gamma = 0;   // 亮度补偿,默认为0
    // 使用addWeighted函数叠加图像,两张图以50%透明度叠加
    addWeighted(image1, alpha, image2, beta, gamma, result);

    // 创建一个名为Draw Shapes Mode 2"的窗口,WINDOW_NORMAL允许调整窗口大小
    namedWindow("Draw Shapes Mode 2", WINDOW_NORMAL);
    // 在窗口中显示图像
    imshow("Draw Shapes Mode 2", result);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

        执行上面的示例代码,运行效果可参考下图。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NACOS 2.4.1如何开启账号密码登录功能

Nacos Server 2.4.0+已正式发布取消管理员用户 nacos 的默认密码支持初始化指定密码。 本章教程,主要介绍如何给nacos加上鉴权,支持通过用户名和密码的方式进行访问nacos页面。 NACOS 2.4.1版本下载地址:https://github.com/alibaba/nacos/releases/tag/2.4.1 1、开启认证功…

驱动:insmod

一、驱动模块的加载 1. 静态 编译进内核2. 动态 编译成模块 如下&#xff1a; 解决方法 结果 led电灯例子 创建一个led.c 修改Makefile、Kconfigmake modulescp drivers/char/led.ko /home/linux/nfs/rootfs开发板 insmod led.ko去 /home/linux/nfs/rootfs 上 写程序.carm-l…

每日掌握一个科研绘图|区域图·24-08-23

小罗碎碎念 为了方便大家获取对应的代码和源数据&#xff0c;从本期推文开始&#xff0c;我将把对应的文件上传至Github仓库&#xff0c;感兴趣的同学自行获取。 仓库地址 https://github.com/Lxltxpku/Share 一、区域图 区域图是一种数据可视化工具&#xff0c;它通过在坐标…

嵌入式人工智能ESP32(7-OLED显示中英文)

1、OLED显示英文 我们之前通过树莓派开发板做过OLED显示&#xff0c;这里就不再赘述OLED显示屏了。直接上接线图与代码。 &#xff08;1&#xff09;Adafruit Adafruit是一家成立于2005年的私营企业&#xff0c;主要业务是设计和制造开源电子硬件。Adafruit在美国设计和制造其…

全栈杂谈第一期:什么是计算机中的并发

什么是计算机中的并发 计算机中的“并发”是一个听起来很复杂的词汇&#xff0c;但我们可以把它简单理解为“同时做很多事情”。想象一下你正在做晚饭&#xff1a;你可以在等水烧开的时候切菜&#xff0c;还可以在等待炖汤时洗碗。尽管你只有一双手&#xff0c;但通过合理安排…

芋道cloud v2.2.0发布,支持模块选配,丢弃简易版

大家知道&#xff0c;芋道cloud拥有商城、CRM、ERP、微信相关等模块&#xff0c;很显然我们在日常开发中不可能一个项目同时拥有这么多模块。但是从gitee上获取代码的时候&#xff0c;只提供了简易版和完整版。简易版本只有最基础的功能&#xff0c;如果想要微信相关的模块&…

浅谈Llama3.1,从结构、训练过程、影响到数据合成

Llama3.1系列模型的开源&#xff0c;真让大模型格局大震&#xff0c;指标上堪比最好的闭源模型比如GPT 4o和Claude3.5&#xff0c;让开源追赶闭源成为现实。 这里给大家分享一篇俊林兄&#xff08;知乎张俊林&#xff09;的一篇解读&#xff0c;主要对LLaMA3.1的模型结构、训练…

RM双轴云台控制

RM机器人上最复杂的控制计构就是双轴云台了&#xff0c;赛场上的情况对双轴云台的控制稳定度与响应灵敏度双方面都提出了很高的要求&#xff0c;云台控制的好坏在一定程度上就能够代表一支队伍的实力。 双轴云台采用的控制算法依然是PID控制算法&#xff0c;关于PID控制算法的…

自动操作一键数据恢复/电子取证

对磁盘模拟扫描修复丢失数据的实验。 先挂载题目磁盘VHD。 Windows系统中打开磁盘管理&#xff0c;-操作&#xff0c;-附加VHD 可以看到已经加载出题目磁盘&#xff0c;接下来打开RStudio数据恢复软件&#xff0c;对其进行扫描。 操作找回丢失/被删除的数据 可以看到已经加载出…

Java入门:06.Java中的方法--进阶04

4方法递归 简而言之就是方法的自身调用。 也可以是方法组自身的调用 递归类似循环&#xff0c;可以实现功能的反复执行。在某些(算法)环境下&#xff0c;比使用循环更轻松。 递归的本质就是方法的不同调用&#xff0c;就会不同的产生栈帧压栈&#xff0c;栈空间有限&#xff…

一个可以搜索页面内超链接的HTML页面

页面效果如上&#xff0c;含有标题&#xff0c;搜索框和一些超链接&#xff0c;在搜索框输入一些文字可以在下方显示含有这些文字的超链接。这里的搜索不仅可以中文&#xff0c;还可以是英文&#xff0c;数字 HTML代码如下 <!DOCTYPE html> <html lang"en&qu…

笔记小结:《利用pytthon进行数据分析》之使用pandas和seaborn绘图

matplotlib实际上是一种比较低级的工具。要绘制一张图表&#xff0c;你组装一些基本组件就行&#xff1a;数据展示&#xff08;即图表类型&#xff1a;线型图、柱状图、盒形图、散布图、等值线图等&#xff09;、图例、标题、刻度标签以及其他注解型信息。 在pandas中&#xf…

polarctf靶场[CRYPTO]显而易见的密码、[CRYPTO]夏多的梦、[CRYPTO]再这么说话我揍你了、[CRYPTO]神秘组织M

[CRYPTO]显而易见的密码 考点&#xff1a;ntlm编码 打开文件&#xff0c;显示内容就是ntlm格式 ntlm解密 在线网站&#xff1a; https://www.cmd5.com/便可得到flag [CRYPTO]夏多的梦 根据题目提示可以猜测为夏多密码 考点&#xff1a;夏多密码 在线加密原理网站&#x…

如何使用ssm实现应急资源管理系统

TOC ssm074应急资源管理系统jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。…

WEB渗透Win提权篇-RDPFirewall

爆破RDP Hydra爆破RDP >hydra -l admin -P /root/Desktop/passwords -S 192.168.0.0 rdpNlbrute MSF开启 >run post/windows/manage/enable_rdp多用户登陆 Mimikatz设置允许多用户登录 >privilege::debug >ts::multirdprdpwrap GitHub - stascorp/rdpwrap: RD…

用5点结构标定3点结构的顺序

在行列可自由变换的条件下&#xff0c;5点结构有34个 (A,B)---6*30*2---(0,1)(1,0) 让A分别是5a1&#xff0c;2&#xff0c;…&#xff0c;34&#xff0c;让B全是0。当收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值&#xff0c;得到 迭代次数 搜索难度 1 3683.965 …

上市公司绿色企业识别数据集(2016-2023年)

数据来源&#xff1a;本数据来源于中国债券信息网和企业年报&#xff0c;参考张小可老师等&#xff08;2024&#xff09;做法&#xff0c;根据上市公司是否发行过绿色债券来认定绿色企业的身份。经过对2016-2023年间发行过绿色债券的企业进行人工统计后&#xff0c;共有164家被…

大模型提示词工程和落地思考

本文是一篇内部的个人分享&#xff08;已无敏感信息&#xff09; &#xff0c;目的是增加产品、开发同学对 LLM 的理解&#xff0c;以降低沟通中的阻力&#xff0c;更好推进落地。 以下经脱敏后的原文: 大模型并不神奇 很多人听到’大模型’这个词可能会觉得很神秘&#xff…

Spring Boot 集成 swagger 3.0 指南

Spring Boot 集成 swagger 3.0 指南 一、Swagger介绍1.springfox-swagger 22.SpringFox 3.0.0 发布 二、Spring Boot 集成 swagger 3.01. 添加Maven依赖2. 创建配置类配置Swagger2.1 创建SwaggerConfig 配置类2.1 创建TestInfoConfig信息配置类 3. 在你的Controller上添加swagg…

【深度学习与NLP】——最全环境配置总指南

目录 一、Anaconda 的环境准备 1.下载和安装 1.1. 下载 1.1.1. 官网下载 1.1.2. 镜像站下载&#xff08;官网下载速度慢可选&#xff09; 1.2. 安装 2. 环境配置 2.1 Windows 平台 2.2 MacOS 和 Linux 平台 3. 环境验证 3.1 Windows 平台 3.2 MacOS 和 Linux 平台 …