python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加
【1】引言
前序学习过程中,掌握了灰度图像和彩色图像的掩模操作:
python学opencv|读取图像(九)用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客
python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖-CSDN博客
也受此启发,尝试直接使用cv2.add()函数让两张图片进行叠加:
python学opencv|读取图像(四十一 )使用cv2.add()函数实现各个像素点BGR叠加-CSDN博客
在此基础上,我们如果进一步尝试,就可以对3张图片进行叠加。
比如,我们已经知晓彩色三通道图像的每一个通道都可以单独设置对应BGR值,它们叠加的效果是新的彩色图像。实际上,这种叠加效果我们早期在没有使用cv2.add()函数的时候,已经悄然获得了:
python学opencv|读取图像(十)用numpy创建彩色图像_cv2 通过numpy创建图像-CSDN博客
此时,在已经、学习了cv2.add()函数的基础上,我们可以进一步验证。
【2】可行性分析
【2.1】未使用cv.add()函数
在python学opencv|读取图像(十)用numpy创建彩色图像_cv2 通过numpy创建图像-CSDN博客文章中,使用的代码为:
import numpy as np # 引入numpy模块
import cv2 as cv # 引入cv2模块
from imageio.v2 import imwrite# 定义图像
t = np.arange(300, 600, 20) # 定义变量,在[300,600)区间,每隔20取一个值
t_max = np.max(t) # 取变量最大值作为像素大小
print('t_max=', t_max) # 输出最大值
image = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image[:, :, 0] = 155 # 第一个通道值
image[:, :, 1] = 200 # 第二个通道值
image[:, :, 2] = 255 # 第三个通道值# 显示和保存定义的图像
cv.imshow('display-pho', image) # 显示图像
cv.imwrite('gray-pho-3.png', image) # 保存图像
cv.waitKey() # 图像不关闭
cv.destroyAllWindows() # 释放所有窗口
这其中的核心代码段,有一个逐层覆盖和叠加的效果:
image[:, :, 0] = 155 # 第一个通道值 image[:, :, 1] = 200 # 第二个通道值 image[:, :, 2] = 255 # 第三个通道值
【2.2】使用cv.add()函数
为验证使用add()函数的叠加效果,在上述代码后面补充一段代码:
image1 = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image1[:, :, 0] = 155 # 第一个图像
image2 = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image2[:, :, 1] = 200 # 第二个图像
image3 = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image3[:, :, 2] = 255 # 第三个图像
img=cv.add(image1,image2) # 第一和第二图像叠加
cv.imshow('display-12', img) # 显示图像
cv.imwrite('gray-pho-12.png', img) # 保存图像
img=cv.add(img,image3) # 第一、第二和第三图像叠加
cv.imshow('display-123', img) # 显示图像
cv.imwrite('gray-pho-123.png', img) # 保存图像
运行代码后,获得的图像为:
图1 gray-pho-3.png-未使用add()函数
图2 gray-pho-123.png-使用add()函数
由图1和图2可见,无论是否使用add()函数,图像叠加的本质都是各个通道的BGR值对应相加,获得的图像效果是一样的。
此外,中间的过渡图像,也就是image1[:, :, 0] = 155和image1[:, :,1] = 200叠加后的图像为:
图3 gray-pho-12.png-使用add()函数
【2.3】使用cv.add()函数+掩模效果
在前述的两个测试中,使用的图像叠加都没有尝试掩模效果。
但add()函数本身允许添加一个mask参数来做掩模效果,为验证掩模效果,继续增加下述代码:
#验证掩模效果
mask=np.zeros((t_max, t_max,1),np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
mask[20:300, 200:500, ] = 200 # 第二个图像
cv.imshow('display-mask', mask) # 显示图像
cv.imwrite('gray-pho-mask.png',mask) # 保存图像
img=cv.add(image1,image2,mask=mask) # 第一和第二图像叠加
cv.imshow('display-12-mask', img) # 显示图像
cv.imwrite('gray-pho-12-mask.png', img) # 保存图像
这里应用掩模效果的核心代码为:
img=cv.add(image1,image2,mask=mask) # 第一和第二图像叠加
代码运行后的掩模效果为:
图4 gray-pho-12-mask.png-使用add()函数
由图4可见,图像只在使用掩模的区域进行了效果叠加,其他区域仍然保留了全0矩阵对应的纯黑色画布特点。
因为刚好掩模的矩阵赋值也是200,和image2的通道赋值一样,为进一步测试,把这个掩模的矩阵赋值改到255,增加下述代码:
mask1=np.zeros((t_max, t_max,1),np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
mask1[20:300, 200:500, ] = 255 # 第二个图像
cv.imshow('display-mask', mask1) # 显示图像
cv.imwrite('gray-pho-mask.png',mask1) # 保存图像
img=cv.add(image1,image2,mask=mask1) # 第一和第二图像叠加
cv.imshow('display-123-mask', img) # 显示图像
cv.imwrite('gray-pho-123-mask.png', img) # 保存图像
此时获得的图像为:
图5 gray-pho-mask.png-掩模
图6 gray-pho-123-mask.png-使用add()函数+掩模
可见,使用掩模效果后,图像依然是image1+image2的效果,且只在掩模控制的区域显示这个叠加效果。
此时的完整代码为:
import numpy as np # 引入numpy模块
import cv2 as cv # 引入cv2模块
from imageio.v2 import imwrite# 定义图像
t = np.arange(300, 600, 20) # 定义变量,在[300,600)区间,每隔20取一个值
t_max = np.max(t) # 取变量最大值作为像素大小
print('t_max=', t_max) # 输出最大值
image = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image[:, :, 0] = 155 # 第一个通道值
image[:, :, 1] = 200 # 第二个通道值
image[:, :, 2] = 255 # 第三个通道值# 显示和保存定义的图像
cv.imshow('display-pho', image) # 显示图像
cv.imwrite('gray-pho-3.png', image) # 保存图像image1 = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image1[:, :, 0] = 155 # 第一个图像
image2 = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image2[:, :, 1] = 200 # 第二个图像
image3 = np.zeros([t_max, t_max, 3], np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
image3[:, :, 2] = 255 # 第三个图像
img=cv.add(image1,image2) # 第一和第二图像叠加
cv.imshow('display-12', img) # 显示图像
cv.imwrite('gray-pho-12.png', img) # 保存图像
img=cv.add(img,image3) # 第一、第二和第三图像叠加
cv.imshow('display-123', img) # 显示图像
cv.imwrite('gray-pho-123.png', img) # 保存图像#验证掩模效果
mask=np.zeros((t_max, t_max,1),np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
mask[20:300, 200:500, ] = 200 # 第二个图像
cv.imshow('display-mask', mask) # 显示图像
cv.imwrite('gray-pho-mask.png',mask) # 保存图像
img=cv.add(image1,image2,mask=mask) # 第一和第二图像叠加
cv.imshow('display-12-mask', img) # 显示图像
cv.imwrite('gray-pho-12-mask.png', img) # 保存图像mask1=np.zeros((t_max, t_max,1),np.uint8) # 定义一个竖直和水平像素均为t_max的全0矩阵
mask1[20:300, 200:500, ] = 255 # 第二个图像
cv.imshow('display-mask', mask1) # 显示图像
cv.imwrite('gray-pho-mask.png',mask1) # 保存图像
img=cv.add(image1,image2,mask=mask1) # 第一和第二图像叠加
cv.imshow('display-123-mask', img) # 显示图像
cv.imwrite('gray-pho-123-mask.png', img) # 保存图像cv.waitKey() # 图像不关闭
cv.destroyAllWindows() # 释放所有窗口
【3】总结
掌握了使用python+opencv实现使用cv2.add()函数进行多图像叠加的技巧,并探索了掩模的影响。
相关文章:

python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加
【1】引言 前序学习过程中,掌握了灰度图像和彩色图像的掩模操作: python学opencv|读取图像(九)用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 python学opencv|读取图像(四十)掩模:三…...

速通Docker === Docker Compose
目录 Docker Compose 简介 Docker Compose 常用命令 使用 Docker Compose 启动 WordPress 普通启动方式(使用 Docker 命令) 使用 Docker Compose 启动 Docker Compose 的特性 Docker Compose 简介 Docker Compose 是一个用于定义和运行多容器 Dock…...

LMI Gocator GO_SDK VS2019引用配置
LMI SDK在VS2019中的引用是真的坑爹,总结一下经验,希望后来的人能少走弯路.大致内容如下: (1) 环境变量 (2)C/C 附加包含目录 E:\GWQ\Gocator\GO_SDK\Gocator\GoSdk E:\GWQ\Gocator\GO_SDK\Platform\kApi (3&#…...
技术之翼,创作之心
引言:初入编程的迷茫与追求 当我第一次接触到编程时,心中充满了既期待又迷茫的情感。那时,我还是一名刚刚踏入大学的学生,面对一门陌生而复杂的学科——计算机科学,我的内心充满了好奇与困惑。课堂上,老师…...
WebSocket异步导出
WebSocket异步导出 1、安装sockjs-client和stompjs2、连接后台3、vite.config.ts 配置反向代理4、导出并实时通信5、 封装WebSocket 文件注册登录(城通网盘) 1、安装sockjs-client和stompjs import SockJS from sockjs-client/dist/sockjs.min.js import Stomp from stompjs2、…...

OS2.【Linux】基本命令入门(1)
目录 1.操作系统是什么? 2.好操作系统的衡量标准 3.操作系统的核心工作 4.在计算机上所有行为都会被转换为硬件行为 5.文件 6.简单介绍一些基本命令 1.clear 2.pwd 3.ls 1.ls -l 2.隐藏文件的创建 3.ls -al 4.ls -ld 5.ls -F(注意是大写) 4.cd 1.cd .. "…...

【二叉树】4. 判断一颗二叉树是否是平衡二叉树。5. 对称二叉树。6. 二叉树的构建及遍历 7. 二叉树的分层遍历 。
判断一颗二叉树是否是平衡二叉树。OJ链接 可以在求树高度的过程中判断树是否平衡 对称二叉树。OJ链接 二叉树的构建及遍历。OJ链接 注意:public static int i最好把static去掉 否则当有多个测试用例时 i无法重新为0二叉树的分层遍历 。OJ链接 但此题要求返回List…...

OS Copilot功能测评:智能助手的炫彩魔法
简介: OS Copilot 是一款融合了人工智能技术的智能助手,专为Linux系统设计,旨在提升系统管理和运维效率。本文详细介绍了在阿里云ECS实例上安装和体验OS Copilot的过程,重点评测了其三个核心参数:-t(模式…...

MFC结构体数据文件读写实例
程序功能将结构体内数组数据写入文件和读出 2Dlg.h中代码: typedef struct Student {int nNum[1000];float fScore;CString sss;}stu; class CMy2Dlg : public CDialog { // Construction public:CMy2Dlg(CWnd* pParent NULL); // standard constructorstu stu1; ... } 2Dl…...
音频 PCM 格式 - raw data
文章目录 raw 音频格式:PCM其他音频格式:mp31. 无损压缩音频(类比 PNG 图像)2. 有损压缩音频(类比 JPEG 图像) 试了一下科大讯飞的音频识别云 api,踩了点坑 与本文无关:讯飞的 api 使…...
关于deepin上运行Qt开发的程序
国产化替代是将来各单位的主流趋势,探索自行开发应用程序在国产操作系统上正常运行是将来的主要工作之一。本文浅尝gui程序在统信社区版——deepin上遇到的小问题。 使用Qt在deepin上做了一个类似gif的帧动画弹窗,在编译运行时,程序可以正常…...

css 如何将字体进行压扁,即水平缩放scaleX
1、下面是来自baidu ai的结果: 2、下面是测试结果: .font-yh {text-align: center;font-family: msyh;display: inline-block; /* 确保transform作用于元素本身 */transform: scaleX(1.5); /* 水平缩放 */ } font-face {font-family: msyh;font-style:…...

C++AVL树(二)详解
文章目录 AVL树旋转单旋右单旋左单旋 双旋左右双旋右左双旋 平衡因子的更新左右双旋右左双旋 判断是不是AVL树时间复杂度分析全部的代码 AVL树 旋转 单旋 单旋是纯粹的一边高 单旋平衡因子是同号 右单旋 a,b,c自身不能发生旋转 并且也不能不向上继续更新(不能停…...
RocketMQ 的 Topic 和消息队列MessageQueue信息,是怎么分布到Broker的?怎么负载均衡到Broker的?
目录 1. Topic 和 MessageQueue 的基本概念 1.1 Topic 1.2 MessageQueue 2. Topic 和 MessageQueue 的分布 2.1 Topic 的创建 2.2 MessageQueue 分配到 Broker 2.3 分布规则 3. 负载均衡机制 3.1 Producer 的负载均衡 3.2 Consumer 的负载均衡 3.3 Broker 的负载均衡…...
无人机核心项目开发系列:从设计到实现的完整解析
无人机核心项目开发系列:从设计到实现的完整解析 01-面试大保健-核心项目-无人机-架构-硬件 1. 无人机项目概述 在这篇博客中,我们将回顾一个遥控四轴无人机的项目。这是一个面向儿童的玩具无人机,具备基础的飞行功能:上升、下…...

浅谈Redis
2007 年,一位程序员和朋友一起创建了一个网站。为了解决这个网站的负载问题,他自己定制了一个数据库。于2009 年开发,称之为Redis。这位意大利程序员是萨尔瓦托勒桑菲利波(Salvatore Sanfilippo),他被称为Redis之父,更…...

Ceisum无人机巡检直播视频投射
接上次的视频投影,Leader告诉我这个视频投影要用在两个地方,一个是我原先写的轨迹回放那里,另一个在无人机起飞后的地图回显,要实时播放无人机拍摄的视频,还要能转镜头,让我把这个也接一下。 我的天&#x…...

【组件库】使用Vue2+AntV X6+ElementUI 实现拖拽配置自定义vue节点
先来看看实现效果: 【组件库】使用 AntV X6 ElementUI 实现拖拽配置自定义 Vue 节点 在现代前端开发中,流程图和可视化编辑器的需求日益增加。AntV X6 是一个强大的图形化框架,支持丰富的图形操作和自定义功能。结合 ElementUI,…...
Vue.js组件开发-如何实现全选反选
在 Vue.js 中实现全选和反选功能,可以通过结合v-model、计算属性和事件处理来完成。 实现思路 • 数据绑定:为每个复选框绑定一个选中状态。 • 全选控制:通过一个复选框控制所有复选框的选中状态。 • 反选控制:通过一个按钮或…...

2025.1.20——四、[强网杯 2019]Upload1 文件上传|反序列化
题目来源:buuctf [强网杯 2019]Upload 1 目录 一、打开靶机,查看信息 二、解题思路 step 1:登陆进去看情况 step 2:大佬来支援——问题在cookie step 3:测试两个思路 1.目录穿越 2.目录扫描 step 4ÿ…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...