当前位置: 首页 > news >正文

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&#xff…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

GitHub 趋势日报 (2025年06月08日)

📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

今日科技热点速览

🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...