10.3拉普拉斯金字塔

实验原理

拉普拉斯金字塔(Laplacian Pyramid)是一种图像表示方法,常被用于图像处理和计算机视觉领域。它是基于高斯金字塔的一种变换形式,主要用于图像融合、图像金字塔的构建等场景。下面简要介绍拉普拉斯金字塔的基本原理。

高斯金字塔(Gaussian Pyramid)

首先,为了理解拉普拉斯金字塔,我们需要了解高斯金字塔的概念。高斯金字塔是一个多分辨率的图像表示方法,通过一系列对原图进行下采样的操作生成不同分辨率的图像序列。每个层是由前一层经过卷积滤波后进行下采样得到的。

拉普拉斯金字塔

拉普拉斯金字塔也是多分辨率表示的一种方式,但与高斯金字塔不同的是,拉普拉斯金字塔记录的是每一层相对于上一层的差异信息。这种金字塔由如下步骤构建:

1. 构建高斯金字塔:从原始图像开始,依次生成每一层的高斯金字塔,每层都是通过应用高斯滤波器后进行下采样(通常是将图像尺寸缩小一半)得到的。

2. 构建拉普拉斯层:对于每一层高斯金字塔,拉普拉斯层是通过以下步骤得到的:

•从较高分辨率的图像生成较低分辨率的图像(即,先下采样再高斯滤波)。

•从较低分辨率的图像生成较高分辨率的图像(即,先上采样再高斯滤波)。

•计算两者的差值,这就是该层的拉普拉斯层。

应用

拉普拉斯金字塔在很多场合都有应用,比如:

•图像融合:可以将多个源图像的拉普拉斯层叠加在一起,从而创建出一个具有多个视角信息的新图像。

•图像压缩:由于拉普拉斯金字塔的每一层都表示了图像的一个细节层次,因此可以用不同的精度来存储每一层,从而实现图像的高效压缩。

•边缘检测:拉普拉斯金字塔中的每一层都可以看作是对应尺度下的边缘信息,因此可以用来进行边缘检测。

在OpenCV(开源计算机视觉库)中,拉普拉斯金字塔(Laplacian Pyramid)是一种多尺度图像表示方法,它用于图像处理和计算机视觉任务中。拉普拉斯金字塔是基于高斯金字塔(Gaussian Pyramid)构建的,通常用于图像融合、图像金字塔之间的差异存储以及图像缩放等操作。

原理
1.高斯金字塔:

首先创建一个高斯金字塔,它是通过连续对原始图像进行模糊和下采样得到的一系列图像。每次生成新的层时,通常会使用一个5x5或3x3的高斯核来对图像进行平滑处理,然后将图像的宽度和高度减半。
2.拉普拉斯金字塔构造:

一旦有了高斯金字塔,就可以构建拉普拉斯金字塔了。对于每个高斯金字塔中的非顶层图像,我们对其进行上采样(通常是尺寸扩大一倍),然后从其上方一层(即更精细的层)减去这个上采样的版本。结果就是该层的拉普拉斯图像,它捕捉了与上一层相比的细节变化。
3.拉普拉斯金字塔应用:
图像融合:可以将两个或多个不同来源的拉普拉斯金字塔对应层相加,然后通过逆过程重建出融合后的图像。
图像压缩:可以仅存储拉普拉斯金字塔的顶部(最粗糙的层),以及每一层的差值,这样可以减少存储空间。
图像金字塔之间的差异存储:这有助于在网络上传输图像时节省带宽。
4.重建图像:为了从拉普拉斯金字塔中恢复原始图像,需要反向操作。先从最顶层开始,进行上采样,并将其与下一层的拉普拉斯图像相加。重复这一过程直到最后一层,就能重建出完整的图像。

在OpenCV中,buildPyramidMultiChannel函数可以用来创建拉普拉斯金字塔,而pyrUp和pyrDown函数则分别用于上采样和下采样操作。不过需要注意的是,直接用于创建拉普拉斯金字塔的函数可能需要你自己实现,因为OpenCV没有直接提供这样的函数,你需要组合使用上述提到的功能来构建拉普拉斯金字塔。

示例代码1

使用C++编写的拉普拉斯金字塔构建示例代码:

#include "pch.h"#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;
using namespace cv;// 定义一个函数来构建拉普拉斯金字塔
vector<Mat> buildLaplacianPyramid(const Mat &src, int levels)
{vector<Mat> gaussianPyramid;vector<Mat> laplacianPyramid;// 创建高斯金字塔gaussianPyramid.push_back(src.clone());Mat temp = src.clone();for (int i = 0; i < levels; ++i) {GaussianBlur(temp, temp, Size(5, 5), 1.5);Mat nextLevel;pyrDown(temp, nextLevel);gaussianPyramid.push_back(nextLevel.clone());temp = nextLevel;}// 创建拉普拉斯金字塔for (int i = gaussianPyramid.size() - 2; i >= 0; --i) {Mat expanded;pyrUp(gaussianPyramid[i + 1], expanded, gaussianPyramid[i].size());Mat laplacian;gaussianPyramid[i] -= expanded;laplacian = gaussianPyramid[i];laplacianPyramid.push_back(laplacian);}// 将最后一个高斯层加入拉普拉斯金字塔laplacianPyramid.push_back(gaussianPyramid.back());return laplacianPyramid;
}int main(int argc, char** argv) 
{/*if (argc != 2){cout << "Usage: ./LaplacianPyramid <Image Path>" << endl;return -1;}*/// 加载图像Mat img = imread("01.png", IMREAD_GRAYSCALE);if (!img.data){cout << "Error opening image" << endl;return -1;}// 设置金字塔的层数int levels = 5;// 构建拉普拉斯金字塔vector<Mat> laplacianPyramid = buildLaplacianPyramid(img, levels);// 显示金字塔的每一层for (size_t i = 0; i < laplacianPyramid.size(); ++i){namedWindow("Laplacian Level " + to_string(i), WINDOW_NORMAL);imshow("Laplacian Level " + to_string(i), laplacianPyramid[i]);waitKey(0);}return 0;
}说明
1. 高斯金字塔: 使用 pyrDown 函数创建高斯金字塔的每一层。
2. 拉普拉斯金字塔: 使用 pyrUp 函数将高斯金字塔的每一层扩大到原始尺寸,并与原图相减得到拉普拉斯层。
3. 显示: 使用 imshow 和 waitKey 来显示每一层的拉普拉斯金字塔。

运行结果1

示例代码2

在OpenCV中,你可以使用C++编写一个简单的程序来构建拉普拉斯金字塔。下面是一个基本的示例,展示如何构建拉普拉斯金字塔,并且显示每层的结果。

#include "pch.h"#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main(int argc, char** argv)
{// 读取图像Mat img = imread("78.jpeg", IMREAD_COLOR);if (img.empty()){cout << "Error: Image cannot be loaded!" << endl;return -1;}int levels = 4;  // 定义金字塔层数vector<Mat> pyr(levels);// 创建高斯金字塔pyr[0] = img;for (int i = 1; i < levels; ++i){pyrDown(pyr[i - 1], pyr[i]);}// 创建拉普拉斯金字塔vector<Mat> lap_pyr(levels);for (int i = 0; i < levels - 1; ++i){Mat up;pyrUp(pyr[i + 1], up, pyr[i].size());lap_pyr[i] = pyr[i] - up;}// 最后一层不需要上采样lap_pyr[levels - 1] = pyr[levels - 1];// 显示每一层for (int i = 0; i < levels; ++i){namedWindow("Level " + to_string(i), WINDOW_NORMAL);imshow("Level " + to_string(i), lap_pyr[i]);}waitKey(0);  // 等待按键退出return 0;
}说明:
读取图像:首先读取一个图像文件,并检查是否成功加载。
创建高斯金字塔:使用pyrDown函数逐层创建高斯金字塔。
创建拉普拉斯金字塔:通过上采样高斯金字塔的每一层,并从它的上一层减去,从而创建拉普拉斯金字塔。
显示图像:使用imshow函数显示拉普拉斯金字塔的每一层。
请确保替换 "path/to/your/image.jpg" 为你的图像文件的实际路径。此外,确保你的环境中已经正确安装了OpenCV,并且包含了必要的头文件和链接库。这个例子简单地展示了如何创建拉普拉斯金字塔,但在实际应用中,你可能还需要处理更多细节,例如边界条件、不同数据类型的处理等。

运行结果2

实验代码3

#include "pch.h"
#include <iostream>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui_c.h>
using namespace std;
using namespace cv;
//#pragma comment(lib, "opencv_world450d.lib")  //引用引入库 //拉普拉斯 边缘计算
void TLaplacian()
{Mat img1, img2, gray_img, edge_img;const char* win1 = "window1";const char* win2 = "window2";const char* win3 = "window3";const char* win4 = "window4";namedWindow(win1, CV_WINDOW_NORMAL);namedWindow(win2, CV_WINDOW_NORMAL);namedWindow(win3, CV_WINDOW_NORMAL);namedWindow(win4, CV_WINDOW_NORMAL);img1 = imread("8.png");if (img1.empty()){cout << "could not found image" << endl;return;}//高斯模糊,去掉噪点GaussianBlur(img1, img2, Size(3, 3), 0, 0);//转为灰度图cvtColor(img2, gray_img, CV_BGR2GRAY);//拉普拉斯Laplacian(gray_img, edge_img, CV_16S, 3);convertScaleAbs(edge_img, edge_img);threshold(edge_img, edge_img, 2, 255, THRESH_OTSU | THRESH_BINARY);imshow(win1, img1);imshow(win2, img2);imshow(win3, gray_img);imshow(win4, edge_img);
}int main()
{TLaplacian();waitKey(0);return 0;
}

运行结果3

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

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

相关文章

【优选算法之二分查找】No.5--- 经典二分查找算法

文章目录 前言一、二分查找模板&#xff1a;1.1 朴素二分查找模板1.2 查找区间左端点模板1.3 查找区间右端点模板 二、二分查找示例&#xff1a;2.1 ⼆分查找2.2 在排序数组中查找元素的第⼀个和最后⼀个位置2.3 搜索插⼊位置2.4 x 的平⽅根2.5 ⼭脉数组的峰顶索引2.6 寻找峰值…

实现人体模型可点击

简化需求&#xff1a;实现项目内嵌人体模型&#xff0c;实现点击不同部位弹出部位名称 一&#xff1a;优先3d&#xff0c; 方案&#xff1a;基于three.js&#xff0c;.gltf格式模型&#xff0c;vue3 缺点&#xff1a;合适且免费的3d模型找不到&#xff0c;因为项目对部位有要…

【记录】Excel|不允许的操作:合并或隐藏单元格出现的问题列表及解决方案

人话说在前&#xff1a;这篇的内容是2022年5月写的&#xff0c;当时碰到了要批量处理数据的情况&#xff0c;但是又不知道数据为啥一直报错报错报错&#xff0c;说不允许我操作&#xff0c;最终发现是因为存在隐藏的列或行&#xff0c;于是就很无语地写了博客&#xff0c;但内容…

Java笔试面试题AI答之单元测试JUnit(5)

文章目录 25. 简述什么是Junit 忽略测试&#xff08;Ignore Test&#xff09;&#xff1f;一、基本概念二、使用方法三、注意事项四、示例 26. 简述什么是Junit 超时测试&#xff08;Timeout Test&#xff09;&#xff1f;Junit 超时测试的主要特点包括&#xff1a;实现方式&am…

全国832个贫困县名单及精准扶贫脱贫数据(2016-2020.11)

自党的十八大以来&#xff0c;通过全党全国各族人民的共同努力&#xff0c;中国成功实现了现行标准下9899万农村贫困人口的全部脱贫&#xff0c;832个贫困县全部摘帽。 摘帽名单 2016年-2020.11全国832个贫困县名单及精准扶贫脱贫数据整理&#xff08;大数据&#xff09;https…

JavaEE:探索网络世界的魅力——玩转UDP编程

文章目录 UDPUDP的特点UDP协议端格式校验和前置知识校验和具体是如何工作的? UDP UDP的特点 UDP传输的过程类似于寄信. 无连接: 知道对端的IP和端口号就直接进行传输,不需要建立连接.不可靠: 没有确认机制,没有重传机制,如果因为网络故障导致该段无法到达对方,UDP协议也不会…

nodejs基于vue+express度假村旅游管理系统设计与实现7t82p

目录 功能介绍数据库设计具体实现截图技术栈技术论证解决的思路论文目录核心代码风格详细视频演示源码获取 功能介绍 实现了一个完整的农家乐系统&#xff0c;其中主要有用户表模块、关于我们模块、收藏表模块、公告信息模块、酒店预订模块、酒店信息模块、景区信息模块、景区…

基于YOLOv5的教室人数检测统计系统

基于YOLOv5的教室人数检测统计系统可以有效地用于监控教室内的学生数量&#xff0c;适用于多种应用场景&#xff0c;比如 自动考勤、安全监控或空间利用分析 以下是如何构建这样一个系统的概述&#xff0c;包括环境准备、数据集创建、模型训练以及如何处理不同类型的媒体输入…

音乐项目,总结

今天的写的思路都挺简单的但是比较繁琐&#xff0c;这个查找&#xff0c;传文件的话可以了&#xff0c;但是没有用分片传送&#xff0c;然后在写音乐播放的处理&#xff0c;<歌单&#xff0c;二级评论&#xff0c;歌曲歌词滚轮播放>三个还没有实现&#xff0c;时间挺紧张…

开源免费的NAS系统-TrueNAS CORE上创建CentOS7虚拟机

目录 文章目录 目录1、说明2、准备工作2.1、准备安装镜像2.1、创建用户2.2、开启 ssh 服务2.3、设置用户权限2.4、上传系统镜像2.5、 添加虚拟机 3、开始安装系统3.1、启动虚拟机3.2、选择语言3.3、配置网络3.4、设置 root 密码3.5、删除光驱3.6、重启虚拟机3.7、使用 ssh 连接…

【2024】前端学习笔记7-颜色-位置-字体设置

学习笔记 1.定义&#xff1a;css2.颜色&#xff1a;color3.字体相关属性&#xff1a;font3.1.字体大小&#xff1a;font-size3.2.字体风格&#xff1a;font - style3.3.字体粗细&#xff1a;font - weight3.4.字体族&#xff1a;font - family 4.位置&#xff1a;text-align 1.…

【Godot4.3】2D程序生成植物概论

概述 Godot的2D程序化植物生成是我一直想要探讨的一个内容&#xff0c;但是一直没有真正开动&#xff0c;在刚过去的中秋节假期期间&#xff0c;在老家无聊&#xff0c;在一个素描本上构思了一系列想法。本篇就基于这些自己的想法介绍一下程序化植物生成的基本思路。不一定对&…

Linux:login shell和non-login shell以及其配置文件

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 shell是Linux与外界交互的程序&#xff0c;登录shell有两种方式&#xff0c;login shell与non-login shell&#xff0c;它们的区别是读取的配置文件不同&#xff0c;本…

Spring6梳理10—— 依赖注入之注入数组类型属性

以上笔记来源&#xff1a; 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09;https://www.bilibili.com/video/BV1kR4y1b7Qc 目录 10 依赖注入之注入数组类型属性 10.1 创建Emp实体类&#xff0c;Dept实体类 10.2…

Linux学习笔记(2)

Linux学习笔记&#xff08;2&#xff09; 知识点&#xff1a; 1.打包、压缩——是什么、为什么、怎么做&#xff1f; 什么是打包、压缩&#xff1f; 打包&#xff1a;把文件合并。 压缩&#xff1a;通过一定算法减少体积。 为什么要进行打包、压缩&#xff1f; 打包&…

数据结构之堆(优先级队列)

“愿独立的你&#xff0c;在随心而行的途中&#xff0c;学会释怀而止&#xff0c;而非一时放纵之后而任性非为” 这好像是我第一次写关于数据结构的文章吧&#xff0c;关于数据结构&#xff0c;那真的是太奥秘了&#xff0c;想领略其中的奥秘&#xff0c;必须得付出相应的努力…

C++:类和对象OJ题

目录 一、求123...n 二、计算日期到天数的转换 三、日期差值 四、打印日期 一、求123...n 这里先把题目链接放在这里求123.....n 描述&#xff1a; 求123...n&#xff0c;要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句&#xff08;A?B:C…

UnLua实现继承

一、在蓝图中实现继承 1、创建父类&#xff0c;并绑定Lua脚本 2、创建子类蓝图&#xff0c;如果先创建的子类&#xff0c;可以修改父类继承 注意&#xff0c;提示选择继承父类的接口&#xff01; 二、在Lua中实现继承 1、在父类Lua脚本中实现函数 BP_CharacterBase.lua func…

一劳永逸:用脚本实现夸克网盘内容自动更新

系统环境&#xff1a;debian/ubuntu 、 安装了python3 原作者项目&#xff1a;https://github.com/Cp0204/quark-auto-save 感谢 缘起 我喜欢看电影追剧&#xff0c;会经常转存一些资源到夸克网盘&#xff0c;电影还好&#xff0c;如果是电视剧&#xff0c;麻烦就来了。 对于一…

【STL】 set 与 multiset:基础、操作与应用

在 C 标准库中&#xff0c;set 和 multiset 是两个非常常见的关联容器&#xff0c;主要用于存储和管理具有一定规则的数据集合。本文将详细讲解如何使用这两个容器&#xff0c;并结合实例代码&#xff0c;分析其操作和特性。 0.基础操作概览 0.1.构造&#xff1a; set<T&…