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

day15 - 使用图像金字塔进行图像拼接

在我们之前的学习过程中,使用的都是恒定大小的图像,但是在某些情况下,我们需要使用不同分辨率的(相同)图像。例如,当在图像中搜索某些东西(例如人脸)时,我们不确定对象将以多大的尺寸显示在图像中。在这种情况下,我们将需要创建一组具有不同分辨率的相同图像,并在所有图像中搜索对象,这些具有不同分辨率的图像集称为“图像金字塔”。

本期我们来实现使用图像金字塔将两张图片融合到一张图片。

完成本期内容,你可以:

  • 了解图像金字塔的原理和应用

  • 掌握上采样和下采样对应的原理和函数

  • 掌握高斯金字塔的实现和应用

  • 掌握拉普拉斯金字塔的实现和应用

若要运行案例代码,你需要有:

  • 操作系统:Ubuntu 16 以上 或者 Windows10

  • 工具软件:VScode 或者其他源码编辑器

  • 硬件环境:无特殊要求

  • 核心库:python 3.6.13, opencv-contrib-python 3.4.11.39,opencv-python 3.4.2.16

点击下载源码


下采样

OpenCV将下采样封装成了cv2.pyrDown()方法。

函数原型:dst = cv2.pyrDown( src[, dstsize[, borderType]] )
dst为输出图像。

参数描述如下:

  • dst:目标图像。
  • src: 原始图像。
  • dstsize:目标图像的大小。
  • borderType:边界类型。

上采样

OpenCV将下采样封装成了cv2.pyrDown()方法。

函数原型:dst = cv2.pyrDown( src[, dstsize[, borderType]] )
dst为输出图像。

参数描述如下:

  • dst:目标图像。
  • src: 原始图像。
  • dstsize:目标图像的大小。
  • borderType:边界类型。

高斯金字塔

高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像。最下面的图像分辨率最高,越往上图像分辨率越低。高斯金字塔的向下采样过程是:对于给定的图像先做一次高斯平滑处理,也就是使用一个大小为的卷积核对图像进行卷积操作,然后再对图像采样,去除图像中的偶数行和偶数列,然后就得到一张图片,对这张图片再进行上述操作就可以得到高斯金字塔。

请添加图片描述

拉普拉斯金字塔

拉普拉斯金字塔是通过源图像减去先缩小后再放大的图像的一系列图像构成的。拉普拉金字塔的图像看起来就像边界图,其中很多像素都是0。他们经常被用在图像压缩中。将降采样之后的图像再进行上采样操作,然后与之前还没降采样的原图进行做差得到残差图。为还原图像做信息的准备。

请添加图片描述

图像融合

图像金字塔的重要应用就是图像融合,它的具体操作是首先对两张图片分别进行降采样,或者采用高斯金字塔法,当降采样到一定程度后,将两张图片合并,这时候由于在降采样时丢失了一部分边缘信息,因此边缘处不匹配的现象就消失了。之后对合并的图像进行上采样,或者采用拉普拉斯金字塔法,使图像回到原来的大小。此时,边缘处的不匹配现象就会明显降低甚至消失。


具体步骤

使用图像金字塔将下列两张图片进行融合。

请添加图片描述
请添加图片描述

步骤一:创建项目工具

创建项目名为使用图像金字塔进行图像融合,项目根目录下新建code文件夹储存代码,新建dataset文件夹储存数据,项目结构如下:

使用图像金字塔进行图像融合                  # 项目名称
├── code                               # 储存代码文件
├── dataset                            # 储存数据文件

注:如项目结构已存在,无需再创建。

步骤二:加载苹果和橙子的两个图像

  1. 导入所需模块:OpenCV、NumPy ;
  2. 读取dataset文件夹下的apple.pngorange.png图片;
  3. 将两张图像均修改为 515*512 的尺寸;

代码实现

# 导入OpenCV、numpy
import cv2
import numpy as np# 读取图片
img = cv2.imread("../dataset/apple.png")
img1 = cv2.imread("../dataset/orange.png")# resize到2的幂次,方便降采样处理
img = cv2.resize(img, (512, 512))
img1 = cv2.resize(img1, (512, 512))

步骤三:定义构建高斯金字塔的函数

  1. 将原图像复制,作为第一张图像;
  2. 高斯平滑处理;
  3. 下采样操作;
  4. 循环上面两步操作,并将得到的图像储存至列表中。

代码实现

# 定义构建高斯金字塔的函数
def gaussian(ori_image, down_times=2):# 1:添加第一个图像为原始图像temp_gau = ori_image.copy()gaussian_pyramid = [temp_gau]for i in range(down_times):# 高斯平滑gaussian_img = cv2.GaussianBlur(temp_gau, (5, 5), 0, 0)# 2:连续存储2次下采样,这样高斯金字塔就有3层temp_gau = cv2.pyrDown(gaussian_img)gaussian_pyramid.append(temp_gau)return gaussian_pyramid

步骤四:定义构建拉普拉斯金字塔的函数

  1. 将高斯金字塔图像列表中的最后一张图像作为第一张图像;
  2. 上采样操作
  3. 与之前还没降采样的原图进行做差得到残差图;
  4. 循环上面两步操作,并将得到的图像储存至列表中。

代码实现

# 定义构建拉普拉斯金字塔的函数
def laplacian(gaussian_pyramid, up_times=2):laplacian_pyramid = [gaussian_pyramid[-1]]for i in range(up_times,0, -1):# i的取值为2,1,0也就是拉普拉斯金字塔有3层temp_pyrUp = cv2.pyrUp(gaussian_pyramid[i])temp_lap = cv2.subtract(gaussian_pyramid[i-1], temp_pyrUp)laplacian_pyramid.append(temp_lap)return laplacian_pyramid

步骤五:对两张图像分别进行高斯金字塔和拉普拉斯金字塔操作

代码实现

# 第一张图进行高斯金字塔计算
gp1 = gaussian(img, down_times=5)# 第二张图进行高斯金字塔计算
gp2 = gaussian(img1,down_times=5)# 第一张图进行拉普拉斯金字塔计算
lp1 = laplacian(gp1,up_times=5)# # 第二张图进行拉普拉斯金字塔计算
lp2 = laplacian(gp2,up_times=5)

步骤六:图像融合

  1. 在每个级别中添加第一张图像的左边和第二张图像的右边,组成新的图像;
  2. 重建图像;
  3. 展示图像。
# 现在在每个级别中添加左右两半图像
merges = []
for i in range(step + 1):w, h, d = lp1[i].shapemerge = np.hstack((lp1[i][:, 0:w // 2 - 10 // 2 ** i], lp2[i][:, w // 2 - 10 // 2 ** i:]))merges.append(merge)
# 现在重建
ls_ = merges[0]
for i in range(1,6):ls_ = cv2.pyrUp(ls_)ls_ = cv2.add(ls_, merges[i])cv2.imshow('Pyramid_blending2.jpg',ls_)cv2.waitKey()
cv2.destroyAllWindows()

图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。

点击下载源码

相关文章:

day15 - 使用图像金字塔进行图像拼接

在我们之前的学习过程中,使用的都是恒定大小的图像,但是在某些情况下,我们需要使用不同分辨率的(相同)图像。例如,当在图像中搜索某些东西(例如人脸)时,我们不确定对象将…...

算法修炼之筑基篇——筑基一层初期(解决01背包问题)

✨博主:命运之光 ✨专栏:算法修炼之练气篇​​​​​ ✨博主的其他文章:点击进入博主的主页 前言:学习了算法修炼之练气篇想必各位蒟蒻们的基础已经非常的扎实了,下来我们进阶到算法修炼之筑基篇的学习。筑基期和练气期…...

JVM的空间结构

目录 一、概述 二、分类 1.程序计数器区域(Program Counter Register): 2.Java虚拟机栈(Stack): 3.堆区(Heap): 4.方法区(Method Area): 5.本地方法栈(Native Method Stack): 一、概述 JVM分为5个主要区域&…...

图像分割的常用算法

图像分割是指将一幅图像划分成多个子区域或像素集合的过程,其中每个子区域或像素集合具有一定的统计特征或语义信息。图像分割是图像处理中的基础任务,其应用涵盖了医学影像、计算机视觉、机器人技术等多个领域。常用的图像分割算法包括: 1.…...

AI歌手真的可以吗

你听过AI歌手吗?近日,“AI孙燕姿”火遍全网,AI孙燕姿翻唱林俊杰的《她说》、周董的《爱在西元前》、赵雷的《成都》等等歌曲让网友听了直呼:“听了一晚上,出不去了。”你认为AI歌手会取代流行歌手成为主流吗&#xff1…...

Kubernetes高级存储

Kubernetes高级存储 PV PVC k8s支持的存储系统很多,全部掌握不现实。为了屏蔽底层存储实现的细节,方便用户使用,k8s引入PV和PVC两种资源对象。 PV(Persistent Volume)持久化卷,对底层共享存储的抽象,一般由k8s管理员进…...

云原生之使用Docker部署docker-compose-ui工具

云原生之使用Docker部署docker-compose-ui工具 一、Docker Compose UI介绍二、检查本地docker环境1.检查系统版本2.检查docker状态 三、下载Docker Compose UI镜像四、部署Docker Compose UI服务1.新建安装目录2.创建Docker Compose UI容器3.检查Docker Compose UI容器状态4.查…...

文心一言 vs GPT4

本周真是科技爱好者的狂欢节。GPT4和文心一言接连发布,AI工具已经开始走进千家万户。 拿文心一言发布会上的几个问题调戏了 GPT4 一下,看看表现如何。 第一个为文心的回答,第二个为GPT4 的回答。 1. 可以总结一下三体的核心内容吗&#xf…...

Tcl-5. format 命令

format 命令和 C 语言中的 printf 和 sprintf 命令类似。它根据一组格式说明来格式化字符 串。此命令不会改变被操作字符串的内容。 [语法]:format spec value1 value2 ... spec 变元包含了格式说明关键词和附加文字。使用%来引入一个关键词,后跟 0 个…...

BloombergGPT: 首个金融垂直领域大语言模型

BloombergGPT: 首个金融垂直领域大语言模型 Bloomberg 刚刚发布了一篇研究论文,详细介绍了他们最新的突破性技术 BloombergGPT。BloombergGPT是一个大型生成式人工智能模型,专门使用大量金融数据进行了训练,以支持金融行业自然语言处理 (NLP…...

CMake深度解析:掌握add_custom_command,精通Makefile生成规则

CMake深度解析:掌握add_custom_command,精通Makefile生成规则 1. CMake简介与基础知识1.1 CMake的基本概念(CMake Basic Concepts)1.1.1 项目(Project)1.1.2 目标(Target)1.1.3 命令…...

基于Yolov5目标检测的物体分类识别及定位(二) -- yolov5运行环境搭建及label格式转换

刚开始跟着网上的教程做,把环境安装错了,后来直接用GitHub的官方教程来安装环境。 地址是yolov5官方团队代码及教程,看readme文件就可以。 系列文章: 基于Yolov5目标检测的物体分类识别及定位(一) -- 数据集…...

Office project 2019安装

哈喽,大家好。今天一起学习的是project 2019的安装,Microsoft Office project项目管理工具软件,凝集了许多成熟的项目管理现代理论和方法,可以帮助项目管理者实现时间、资源、成本计划、控制。有兴趣的小伙伴也可以来一起试试手。…...

【leetcode-mysql】1251. 平均售价

题目: Table: Prices ---------------------- | Column Name | Type | ---------------------- | product_id | int | | start_date | date | | end_date | date | | price | int | ---------------------- (product_id,start_date,end_dat…...

Razor代码复用

1.布局&#xff08;Layout&#xff09;复用 Layout的使用&#xff0c;就像WebForm的模板页一样&#xff0c;甚至会更加简单&#xff0c;更加方便和明了。 要使用Layout&#xff0c;首先要在模板页相应的位置添加RenderBody()方法&#xff1a; <!DOCTYPE html><html la…...

PRL:上海交大张文涛团队实现量子材料相关突破

来源&#xff1a;上海交通大学 近期&#xff0c;上海交通大学物理与天文学院张文涛研究组利用自行研制的高能量和高时间分辨率角分辨光电子能谱系统对量子材料1T-TiSe₂电子结构进行了超快激光操控研究。利用超快光激发与电荷密度波相有关的相干声子&#xff0c;引起晶格内原子…...

impala中group_concat()函数无法对内容进行order by

描述&#xff1a; 使用的是impala数据库&#xff0c;假设有四笔数据&#xff0c;是无序的&#xff0c;业务上要求将其行转列成一行数据&#xff0c;并且里面的数据要按从小到大排序。 过程&#xff1a; 猜测&#xff1a; 数据库Oracle、Mysql、MSsql等支持group_concat中使…...

MySQL 数据库全局变量中文解释

NameValueauto_increment_incrementAUTO_INCREMENT 字段值的自增长步长值。auto_increment_offsetAUTO_INCREMENT 字段值的初始值。autocommit指示新连接的默认提交模式是否启用。automatic_sp_privileges控制是否在存储过程上创建或更改时自动分配特定权限。back_log在开始拒绝…...

设计模式之~状态模式

状态模式&#xff08;State&#xff09;&#xff0c;当一个对象的内部状态改变时允许改变其行为&#xff0c;这个对象看起来像是改变了其类。 能够让程序根据不同的外部情况来做出不同的响应&#xff0c;最直接的方法就是在程序中将这些 可能发生的外部情况全部考虑到&#xff…...

【21JavaScript break 和 continue 语句】JavaScript中的break和continue语句:控制循环流程的关键技巧

JavaScript break 和 continue 语句 在JavaScript中&#xff0c;break和continue是两个关键字&#xff0c;用于控制循环结构的执行流程。 break语句 break语句用于中断循环并跳出循环体&#xff0c;使程序执行流程继续到循环之后的下一行代码。 在for循环中使用break for (…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...