【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合

OpenCV 例程200篇 总目录-202205更新


【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合


图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步降低的图像集合。从底层图像可以看清更多细节,从顶层图像可以看到更多的轮廓特征。

在计算高斯金字塔时,不断进行高斯滤波和下采样,丢失了高频信息。为了描述这些高频信息,将通过原图像减去先缩小后放大的图像的一系列差分图像,定义为拉普拉斯金字塔(Laplacian Pyramid)。


6.3 基于拉普拉斯金字塔的图像融合

图像融合的目的就是使两幅图像的重叠区域过渡自然且平滑。

拉普拉斯金字塔将源图像分解到不同的频带,越高频的图像信息越到上层。在相同显示尺寸下比较不同分辨率的拉普拉斯图像,可以发现不同尺度下关注的细节是不同的,低分辨率下关注的是较大尺度的基本纹理,而高分辨率下关注的是更精细的纹理。

金字塔图像融合过程,是在不同尺度、不同空间分辨率和不同分解层上分别进行的,也称为多波段融合(Multi-band Blending)。多波段融合的思想,是先对多幅图像分别构建拉普拉斯金字塔,然后对同一层图像(相同频段)按一定规则融合,对融合后的图像金字塔重建得到融合图像。

在这里插入图片描述

在上一个例程的基础上,通过掩模图像 mask 实现图像融合,将前景图像叠加到背景图像的指定位置,通过拉普拉斯金字塔在不同频段层次上进行图像融合。

简单地,融合区域中的像素值采用前景图像和背景的掩模加法计算:
P(i,j)=ωPA(i,j)+(1−ω)PB(i,j)P(i,j) = \omega P_A(i,j) + (1-\omega) P_B(i,j) P(i,j)=ωPA(i,j)+(1ω)PB(i,j)

ω\omegaω 为掩模图像,前景区域为黑色遮罩;(1−ω)(1-\omega)(1ω)为逆遮罩,前景区域白色开窗,其它区域黑色。

算法原理:

(1)读取背景图像和前景图像,指定叠加位置,将前景图像调整到指定的大小。
(2)生成掩模图像 mask,标识叠加前景的位置。
(3)建立背景图像和前景图像的高斯金字塔和拉普拉斯金字塔。
(4)基于掩模图像将顶层高斯金字塔、各层拉普拉斯金字塔的背景和前景图像分别进行加权融合。
(5)从顶层的高斯金字塔融合图像开始重建融合图像,与各层拉普拉斯金字塔融合图像相加,得到重建的各层高斯金字塔融合图像,直到底层高斯金字塔融合图像 G0 即为重建的结果。


例程:1.89 基于掩模的拉普拉斯金字塔图像融合

    # 1.89:基于掩模的金字塔图像融合img1 = cv2.imread("../images/seaside02.png")  # 背景图像img2 = cv2.imread("../images/seagull02.png")  # 添加的前景图像xmin, ymin, w, h = 256, 64, 200, 200  # 矩形 ROI 位置: (ymin:ymin+h, xmin:xmin+w)levels = 5# 调整尺寸,将背景图片调整到 power(2,levels) 的整数倍imgBack = cv2.resize(img1, (512, 512), interpolation=cv2.INTER_CUBIC)# h = round(w * img2.shape[0]/img2.shape[1])  # 调整 ROI 尺寸与前景图像尺寸匹配front = cv2.resize(img2, (w+50, h+50))  # 将前景图像调整到指定大小 (w,h)imgFront = np.zeros(imgBack.shape, dtype=np.uint8)  # 与 imgback 尺寸相同的黑色图像imgFront[ymin-25:ymin+h+25, xmin-25:xmin+w+25] = frontmask0 = np.ones((imgBack.shape[:2]), dtype=np.uint8)  # 返回与图像 imgback 尺寸相同的全1数组mask0[ymin:ymin+h, xmin:xmin+w] = 0  # 掩模图像,ROI 为黑色bg = cv2.bitwise_and(imgBack, imgBack, mask=mask0)  # 生成背景,mask 遮罩区域黑色fg = cv2.bitwise_and(imgFront, imgFront, mask=1-mask0)  # 生成前景,前景以外区域黑色stack = cv2.add(bg, fg)  # 直接合成前景与背景# 图像向下取样, 构造高斯金字塔: [原图,下取样1次,下取样2次,下取样3次,下取样4次]gaussPyrB, gaussPyrF, maskLPyr = [imgBack], [imgFront], [mask0]for i in range(1, levels):  # 计算第 i 层高斯金字塔gaussPyrB.append(cv2.pyrDown(gaussPyrB[i-1]))gaussPyrF.append(cv2.pyrDown(gaussPyrF[i-1]))maskLPyr.append(cv2.resize(maskLPyr[i-1], dsize=None, fx=0.5, fy=0.5))# 图像向上取样, 构造拉普拉斯金字塔 [第1层残差,第2层残差,第3层残差,第4层残差]lapPyrB, lapPyrF = [], []  # 从最顶层开始恢复for i in range(levels-1):  # 拉普拉斯金字塔有 4 层: 0,1,2,3lapB = gaussPyrB[i] - cv2.pyrUp(gaussPyrB[i+1])  # 残差lapPyrB.append(lapB)lapF = gaussPyrF[i] - cv2.pyrUp(gaussPyrF[i+1])  # 残差lapPyrF.append(lapF)# 基于掩模图像的拉普拉斯加权融合lapFusion = []for i in range(levels-1):  # 拉普拉斯金字塔共 4 层: 0,1,2,3mask = maskLPyr[i]  # 当前分辨率的掩模遮罩,前景区域黑色遮罩maskInv = 1 - mask  # 生成逆遮罩,前景区域白色开窗,前景以外区域黑色bg = cv2.bitwise_and(lapPyrB[i], lapPyrB[i], mask=mask)  # 生成背景,mask 遮罩区域黑色fg = cv2.bitwise_and(lapPyrF[i], lapPyrF[i], mask=maskInv)  # 生成前景,前景以外区域黑色lapStack = cv2.add(bg, fg)  # 前景与背景合成,得到当前分辨率的拉普拉斯融合图像lapFusion.append(lapStack)# 拼接高斯金字塔顶层 G4: (32,32)mask = maskLPyr[levels-1]  # 当前分辨率的掩模遮罩,前景区域黑色遮罩maskInv = 1 - mask  # 生成逆遮罩,前景区域白色开窗,前景以外区域黑色bg = cv2.bitwise_and(gaussPyrB[levels-1], gaussPyrB[levels-1], mask=mask)  # 生成背景,mask 遮罩区域黑色fg = cv2.bitwise_and(gaussPyrF[levels-1], gaussPyrF[levels-1], mask=maskInv)  # 生成前景,前景以外区域黑色gaussStack = cv2.add(bg, fg)  # 前景与背景合成,得到叠加图像 (32,32)plt.figure(figsize=(10, 7))plt.subplot(231), plt.axis('off'), plt.title("Origin")plt.imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))plt.subplot(232), plt.axis('off'), plt.title("Stacked")plt.imshow(cv2.cvtColor(stack, cv2.COLOR_BGR2RGB))fusion = gaussStack  # 从高斯金字塔顶层 G4:(32,32) 开始逐层复原for i in range(levels-1, 0, -1):  # 拉普拉斯金字塔有 4 层: 3,2,1,0pyrG = cv2.pyrUp(fusion)  # # 上采样,图像尺寸加倍fusion = lapFusion[i-1] + cv2.pyrUp(fusion)plt.subplot(2,3,levels-i+2), plt.axis('off'), plt.title("G{}: {}".format(i-1,fusion.shape[:2]))plt.imshow(cv2.cvtColor(fusion, cv2.COLOR_BGR2RGB))plt.tight_layout()plt.show()

在这里插入图片描述



(本节完)


版权声明:

OpenCV 例程200篇 总目录-202205更新
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124866268)

Copyright 2022 youcans, XUPT
Crated:2022-5-20


欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔
【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔
【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像
【youcans 的 OpenCV 例程200篇】188.基于拉普拉斯金字塔的图像融合
【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合
【youcans 的 OpenCV 例程200篇】190.基于图像分割的图像融合
【youcans 的 OpenCV 例程200篇】191.基于图像分割的金字塔图像融合
【youcans 的 OpenCV 例程200篇】192.Gabor 滤波器组的形状
【youcans 的 OpenCV 例程200篇】193.基于Gabor 滤波器的特征提取
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】

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

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

相关文章

中奖程序

使用Java做了一个中奖程序,程序中已经设置中奖的号码,根据文本提示会让你输入四个数字,当你输入你的四个数字之后程序会给出你是否中奖的结果显示。 结果演示 代码演示 package com.ten; import java.util.Scanner; public class ZhongJi…

java search 不能使用方法_java – 无法使用TERMS QUERY从ELASTIC SEARCH查询字母数字字段...

我试图使用TERMS QUERY从索引查询字母数字值,但它没有给我输出.查询:{"size" : 10000,"query" : {"bool" : {"must" : {"terms" : {"caid" : [ "A100945","A100896" ]}}}},"…

【youcans 的 OpenCV 例程200篇】190.基于图像分割的图像融合

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】190.基于图像分割的图像融合 两张图像直接进行加法运算后图像的颜色会改变,通过加权加法实现图像混合后图像的透明度会改变,都不能实现图像的叠加。 实现图像的叠加,需要…

【youcans 的 OpenCV 例程200篇】191.基于图像分割的金字塔图像融合

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】191.基于图像分割的金字塔图像融合 拉普拉斯金字塔将源图像分解到不同的频带,越高频的图像信息越到上层。在相同显示尺寸下比较不同分辨率的拉普拉斯图像,可以发现不同尺度下关注的细…

java103 101 104 101_编写一个java程序将100,101,102,103,104,105这6个数以数组的形式写入到D:\\test.t...

展开全部你问的不明白,我在代码里给你写了,你自己看吧import java.io.FileWriter;import java.io.IOException;import java.util.Date;import java.util.Scanner;public class Test {public static void main(String[] args) {// 100,101,102,103,104,10…

IDEA快捷生成代码

在开发中我们常用到了许多如for循环,输入输出,if语句等,那么我们如何使用IDEA开发工具自动生成能让我们快速的编写的模板代码呢??? psvm //生成main方法:public static void main(String[] args) {}sout /…

【youcans 的 OpenCV 例程200篇】192.Gabor 滤波器组的形状

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】192.Gabor 滤波器组的形状 6.5 Gabor 滤波器 Gabor 变换是一种加窗短时傅里叶变换,以高斯函数作为短时傅里叶变换的窗函数,因此可以在频域不同尺度、不同方向上提取特征。 Gabor 函…

悬浮窗java_Java制作一个简易的悬浮窗/PPT悬浮窗

电脑日常使用过程中,我们常常可以看到许多软件有悬浮窗,方便快捷,甚至有的还可以在PPT里面使用。这是怎么实现的呢?今天我就来分享一下Java制作一个简单悬浮窗的方法,可以在PPT里面使用。运行效果:其实悬浮…

【youcans 的 OpenCV 例程200篇】193.基于Gabor 滤波器的特征提取

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】193.基于Gabor 滤波器的特征提取 6.5 Gabor 滤波器 Gabor 变换是一种加窗短时傅里叶变换,以高斯函数作为短时傅里叶变换的窗函数,因此可以在频域不同尺度、不同方向上提取特征。 G…

java设置行显示复选框_java spring cheakbox复选框怎么行或者列删除添加

展开全部你好!使用原62616964757a686964616fe78988e69d8331333431353366生js实现,还是可以使用其他框架?我这里有个基于jquery的实现:$(document).ready(function(){function Info(id, name, birthday, workDate, skill, experien…

MyEclipse生成常用方法

我们使用Eclipse工具开发的时候,有很多的代码我们是不用写的,我们可以直接生成我们想要的方法,那么怎么生成我们经常使用的方法呢??? 首先打开我们的MyEclipse工具 到代码编辑页面,在已经定义好…

【youcans 的 OpenCV 例程200篇】194.寻找图像轮廓(cv.findContours)

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】194.寻找图像轮廓(cv.findContours) 1. 轮廓 轮廓是一系列相连的像素点组成的曲线,代表了物体的基本外形。轮廓常用于形状分析和物体的检测和识别。 边缘检测根据灰度的…

java线程池执行器_Java线程池ThreadPoolExecutor的使用

Java线程池ThreadPoolExecutor的使用ThreadPoolExecutor就是我们用来实现线程的一个执行器,它实现了Excutor和ExecutorService接口。Excutor接口只定义了一个方法就是execute用来执行任务。ExecutorService继承于Excutor并添加了一些其他的执行任务的方法和管理线程…

密码强度显示

使用HTML,CSS及JS实现注册功能中密码强度的显示&#xff0c;根据输入的密码判断并显示用户输入密码的强度等级是高还是低等。 效果演示 代码演示 html内容 <div class"container"><div class"userName-wrapper"><label for"userN…

【youcans 的 OpenCV 例程200篇】195.绘制图像轮廓(cv.drawContours)

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】195.绘制图像轮廓&#xff08;cv.drawContours&#xff09; 1. 轮廓 轮廓是一系列相连的像素点组成的曲线&#xff0c;代表了物体的基本外形。轮廓常用于形状分析和物体的检测和识别。 边缘检测根据灰度的…

java终结方法_Java终结任务:Callable和Future

在这里首先介绍下Callable和Future&#xff0c;我们知道通常创建线程的2种方式&#xff0c;一种是直接继承Thread&#xff0c;另外一种就是实现Runnable接口&#xff0c;但是这两种方式创建的线程不返回结果&#xff0c;而Callable是和Runnable类似的接口定义&#xff0c;但是通…

【youcans 的 OpenCV 例程200篇】196.图像的矩和不变矩(cv.moments)

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】196.图像的矩和不变矩&#xff08;cv.moments&#xff09; 2. 轮廓的特征描述 在对实际图像进行轮廓查找时&#xff0c;得到的轮廓数量很多。获取轮廓后&#xff0c;通常基于轮廓的特征进行筛选、识别和处…

Spring boot 项目目录结构详解

对SpringBoot项目目录进行分层显示能够使我们的开发思路更加的明确&#xff0c;代码内容更加清晰易懂&#xff0c;下面向大家讲解一下项目目录结构。 代码层的结构 根目录&#xff1a;com.springboot 1.工程启动类(ApplicationServer.java)置于com.springboot.build包下 2.实…

【youcans 的 OpenCV 例程200篇】197.轮廓的基本特征

OpenCV 例程200篇 总目录-202205更新 文章目录【youcans 的 OpenCV 例程200篇】197.轮廓的基本特征2. 轮廓的特征描述2.2 轮廓的面积、周长、质心和近似多边形2.2.1 轮廓的面积2.2.2 轮廓的周长2.2.3 轮廓的质心2.2.4 轮廓的近似2.2.5 轮廓的凸包&#xff08;凸壳&#xff09;例…

Idea 项目导入

我们在刚开始使用新的开发工具IDEA的时候会遇到我们想要导入一个外部项目却不知从何下手&#xff0c;下面我就教给大家如何使用IDEA导入一个外部的项目。 Idea 导入 外部项目 1.点击 file — new 2.打开路径地址&#xff0c;选择需要导入的项目 3.选择创建—next 4.默认—…