matlab自定义函数实现图像小波变换

matlab中提供了小波变换函数lwt和ilwt,可以方便地实现提升小波变换。

我们按照小波变换的定义,粗糙地实现一个针对图像的小波变换,如下:


% 使用方法:
img = imread('lena256.bmp');  % 假设lena.png是灰度图像
subplot(2,2,1),imshow(img,[]);title('原始图像');
[m,n]=size(img);
result = wavelet_transform(img);
subplot(2,2,2),imshow(result,[]);title('小波');
subplot(2,2,3),imshow(result(1:m/2,1:n/2),[]);title('小波LL');
image = inverse_wavelet_transform(result);
subplot(2,2,4),imshow(image,[]);title('粗糙复原');

function temp = wavelet_transform(image)
% 对输入图像进行一次5/3小波变换
% image: 输入的灰度图像
% LL, LH, HL, HH: 分解得到的四个子带图像
% 预处理 - 将图像转为double类型
image = double(image);

% 水平方向提升小波变换
[rows, cols] = size(image);
temp = zeros(size(image));  % 用于存储水平方向处理后的临时结果
for i = 1:rows
    [sL, dL] = lifting_scheme(image(i, :));
    temp(i, 1:end/2) = sL;  % 放在前面
    temp(i, end/2+1:end) = dL;  % 放在后面
end

% 垂直方向提升小波变换
for j = 1:cols
    [sL, dL] = lifting_scheme(temp(:, j)');
    temp(1:end/2,j) = sL;  %放前面
    temp(end/2+1:end,j) = dL;  %放后面
end

end

function [s, d] = lifting_scheme(x)
% 提升小波分解
% 输入序列 x 应为偶数长度
% 输出 s 为近似系数序列,d 为细节系数序列

% 分裂步骤
e = x(1:2:end);
o = x(2:2:end);

% 预测步骤
p = (e + [e(2:end), e(end)]) / 2;  % 使用边界延拓对最后一个元素进行处理
d = o - p;  % 计算细节系数

% 更新步骤
u = (d + [d(2:end), d(end)]) / 4;  % 类似地处理最后一个元素
s = e + u;  % 更新近似系数
end


function image = inverse_wavelet_transform(temp)
% 对输入的小波变换结果进行逆变换
% temp: 小波变换的结果
% image: 重建后的灰度图像

% 先进行垂直方向的逆变换
[rows, cols] = size(temp);
image = zeros(size(temp));  % 用于存储垂直方向处理后的临时结果
for j = 1:cols
    sL = temp(1:end/2, j)';
    dL = temp(end/2+1:end, j)';
    image(:, j) = inverse_lifting_scheme(sL, dL);
end

% 再进行水平方向的逆变换
for i = 1:rows
    sL = image(i, 1:end/2);
    dL = image(i, end/2+1:end);
    image(i, :) = inverse_lifting_scheme(sL, dL);
end

% 后处理 - 将图像转为uint8类型(如果需要)
image = uint8(image);

end

function x = inverse_lifting_scheme(s, d)
% 提升小波重建
% s: 近似系数序列
% d: 细节系数序列
% x: 重建后的序列

% 逆更新步骤
u = (d + [d(2:end), d(1)]) / 4;  % 注意这里首尾相接的方式不同于上面
e = s - u;

% 逆预测步骤
p = (e + [e(1), e(1:end-1)]) / 2;  % 同理,这里使用的也是不同的边界延拓方式
o = d + p;

% 合并步骤
x(1:2:length(e)*2) = e;
x(2:2:length(o)*2) = o;

end



%% 下面的代码进行图像本身的拓边,保证在预测、更新过程中能被除尽
% % 检查 e 和 o 的长度,确保它们匹配
% if length(e) > length(o)
%     % 如果 e 的长度比 o 长,则需要扩展 o
%     o(end+1) = 2 * o(end) - e(end); % 可以是其他边界扩展策略
% end

%% 下面的代码涉及到边界拓展模式,可以作为参考。

% function [s, d] = lifting_scheme(x)
%     % 提升小波分解
%     % 输入序列 x 应为偶数长度
%     % 输出 s 为近似系数序列,d 为细节系数序列
%
%     % 分裂步骤
%     e = x(1:2:end);
%     o = x(2:2:end);
%
%     % 预测步骤
%     p = zeros(1, length(o));
%     p(1) = e(1);  % 对于序列的首端,直接取值(或使用其他边界延拓策略)
%     p(2:end) = (e(1:end-1) + e(2:end)) / 2;  % 平均相邻的e值进行预测
%     d = o - floor(p);
%
%     % 更新步骤
%     u = zeros(1, length(e));
% %     u(1:end-1) = (d(1:end-1) + [d(2:end), 0]) / 4;  % 更新e值,除最后一个d外
%     u(1:end-1) = (d(1:end-1) + d(2:end)) / 4;  % 更新e值,除最后一个d外
%     u(end) = (d(end) + d(end-1)) / 4;  % 最后一个e值的更新
%     s = e + floor(u);
% end

% function [s, d] = lifting_scheme(x)
% % 提升小波分解
% % 输入序列 x 应为偶数长度
% % 输出 s 为近似系数序列,d 为细节系数序列
%
% % 分裂步骤
% e = x(1:2:end);
% o = x(2:2:end);
%
% %     % 预测步骤
% %     p = [e(1); (e(1:end-1) + e(2:end)) / 2];  % 对于序列的首端,使用边界延拓
% %     d = o - floor(p);
% %
% %     % 更新步骤
% %     u = [(d(1) + d(2)) / 4; (d(1:end-1) + d(2:end)) / 4];
% %     s = e + floor(u);
%
% % 预测步骤
% % 对于序列的首端和末端,使用边界延拓
% p = [(e(1) + e(2)) / 2; (e(1:end-1) + e(2:end)) / 2; (e(end-1) + e(end)) / 2];
% p = p(1:length(o)); % 使 p 和 o 长度一致
% d = o - floor(p);
%
% % 更新步骤
% u = [(d(1) + d(2)) / 4; (d(1:end-1) + d(2:end)) / 4; (d(end) + d(end-1)) / 4];
% u = u(1:length(e)); % 使 u 和 e 长度一致
% s = e + floor(u);
% end

运行结果如下:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单细胞转录组数据分析的10大软件/流程

单细胞数据分析现在已经有上千个软件工具可供使用了,这为用户带来便利的同时也造成了选择困难。就像时间一样,一个表,没问题,但如果有两个表,时间还不一样,该信谁的呢? 正好我们前面一篇文章介绍…

Windows10更新失败 错误 0x80070643、KB5034441的解决方法之二

Windows10更新失败 错误 0x80070643、KB5034441 在知乎Windows10更新失败 错误 0x80070643、KB5034441的原因分析和几个解决方法 - 知乎 参考文章进行操作,更详细信息自己看上面链接。 我电脑的硬盘是mbr格式,而且没有划分恢复分区。 Microsoft Windo…

JS(react)图片压缩+图片上传

上传dome var fileNodeTakeStock: any createRef();<inputref{fileNodeTakeStock}onChange{showPictureTakeStock}style{{ display: "none" }}id"fileInpBtn"type"file"accept"image/*" //限制上传格式multiple{false}capture&qu…

C++继承与多态

一&#xff0c;继承 1&#xff0c;继承定义 继承是C三大特性之一。C有类型的复用&#xff1a;类型模板&#xff0c;函数的复用&#xff1a;函数重载。而继承其本质是一种类的复用&#xff0c;使得程序员可以在原有类特性之上进行扩展来产生新的类&#xff0c;原有的类称为父类…

【深度学习】全连接神经网络

全连接神经网络 全连接神经网络的结构 整体结构 神经网络:类似神经元,前一层可以不断地传递给下一层。 神经网络模型由多个单元结构组成。 单元结构 单元结构的数学公式: a = h ( w x + b ) a=h(wx+b) a=h(wx+b) h(x):激活函数 比如sigmoid就是激活函数之一隐藏层大多…

Collections集合工具类-JAVA

java.util.Collections:是个集合工具类它不是集合&#xff0c;而是集合的工具类 常用 API&#xff1a;注意 binarySearch 方法要求元素有序 方法实现&#xff1a; public class Test01 {public static void main(String[] args) {ArrayList<String>list1new ArrayList…

TPH-YOLOv5:基于Transformer预测头改进的YOLOv5开发构建麦穗检测计数分析系统

关于小麦麦穗或者是麦粒相关的开发实践不多&#xff0c;但前文也有所涉及&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《基于轻量级yolov5nCBAM开发构建全球小麦麦穗智能检测计数系统》 《基于YOLOv5[n/s/m/l/x]全系列参数模型开发构建小麦麦穗颗粒智能化精准检…

TRIZ经典矛盾矩阵.exe

TRIZ经典矛盾矩阵.exe 一、概要二、技术细节I&#xff0e;函数open_dialog&#xff08;&#xff09;和open_version_dialog&#xff08;&#xff09;II&#xff0e;函数resolvent&#xff08;&#xff09;III&#xff0e;函数Invention_Principle_Content&#xff08;&#xff…

svn 安装路径

SVN客户端安装&#xff08;超详细&#xff09; 一、SVN客户端安装 1、下载安装包地址&#xff1a;https://tortoisesvn.net/downloads.html 此安装包是英文版的&#xff0c;还可以下载一个语言包&#xff0c;在同界面的下方 一直点击下一步&#xff0c;直到弹出选择红框 然…

You Only Look Once

You Only Look Once 真方便, 一行代码, 直接输出超炫效果图_哔哩哔哩_bilibili使用yolov8中等模型对视频进行分割, 视频播放量 465、弹幕量 0、点赞数 7、投硬币枚数 4、收藏人数 3、转发人数 2, 视频作者 宝安钢铁侠, 作者简介 一个分享国产电子DIY的阿婆主,啥也不会,就想分…

qt5-入门-信号槽理解+QMainWindow

参考&#xff1a; Qt 深入了解信号槽_w3cschool https://www.w3cschool.cn/learnroadqt/wz3t1j47.html Qt MainWindow_w3cschool https://www.w3cschool.cn/learnroadqt/uqjl1j4b.html 本地环境&#xff1a; win10专业版&#xff0c;64位 信号槽 最简单的例子&#xff1a;写一…

spring cache的使用(Redis)

要在Spring Boot应用中使用Redis作为缓存&#xff0c;你需要遵循一些步骤来配置和使用Redis。以下是使用Spring Cache抽象与Redis进行整合的详细说明&#xff1a; 1. 添加依赖 首先&#xff0c;需要在pom.xml中添加Spring Boot的Redis starter依赖以及缓存的starter依赖。这会…

我的创作纪念日和前端碎碎念

机缘 作为一个前端开发者&#xff0c;我一直热衷于将设计和技术相结合&#xff0c;尽可能提升用户体验。我最初成为创作者的初心源于学习记录&#xff0c;把创作当作一个笔记&#xff0c;希望把自己遇到的问题&#xff0c;以及学习到的实用技巧记录下来&#xff0c;方便学习回…

新书速览|Docker与Kubernetes容器运维实战

帮助读者用最短的时间掌握Docker与K8s运维技能 内容简介 随着云计算和容器技术的发展&#xff0c;Docker与Kubernetes已经成为各个企业首选的部署工具&#xff0c;使用它们可以提高系统的部署效率和运维能力&#xff0c;降低运维成本。本书是一本为初学者量身定制的Docker与Kub…

nodejs+vue+mysql校园失物招领网站38tp1

本高校失物招领平台是为了提高用户查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了用户和管理员这两者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;尽可能优化界…

nodejs+vue+ElementUi学生兼职招聘求职系统b8t93

浏览器&#xff1a;谷歌浏览器课题主要分为三大模块&#xff1a;即管理员模块和学生、企业模块&#xff0c;主要功能包括&#xff1a;学生、企业、岗位类型、招聘信息、应聘信息、投诉建议等&#xff1b; 运行软件:vscode 前端nodejsvueElementUi 语言 node.js 框架&#xff1…

【MBtiles数据索引和服务发布】GeoServer改造Springboot番外系列二

xyz地图服务访问示例&#xff1a;http://192.168.1.240:8081/gmserver/raster/xyz/firstWP:Imagery-raster/{z}/{x}/{y}.jpg 访问示例如下&#xff1a; mbtiles目录结构 根据z&#xff0c;x&#xff0c;y获取对应mbtiles文件路径的工具方法 说明&#xff1a;重点是使用getMb…

STM32——I2C

通信协议见&#xff08;STM32——SPI&#xff09; 一、I2C协议 1.1 I2C协议介绍&#xff1b; I2C是&#xff08;Inter IC Bus&#xff09;是由Philips公司开发的一种通用数据总线&#xff1b; 有多根通信线&#xff1b; 一根SDA&#xff08;串行通信线&#xff09;&#xf…

PySpark(一)Spark原理介绍、PySpark初体验及原理

Spark简介 Apache Spark是用于大规模数据&#xff08;large-scala data&#xff09;处理的统一&#xff08;unified&#xff09;分析引擎&#xff0c;其特点就是对任意类型的数据进行自定义计算。 Spark VS Hadoop 尽管Spark相对于Hadoop而言具有较大优势&#xff0c;但Spark并…

Three.js 纹理贴图 - 环境贴图 - 纹理贴图 - 透明贴图 - 高光贴图

文章目录 Three.js 纹理贴图纹理贴图 map属性纹理贴图的映射方式 texture.Mapping纹理加载器 THREE.TextureLoader监听单个材质监听多个材质 - LoadingManager类 1. 颜色贴图与材质的颜色2.渲染效果&#xff1a;UV坐标 - 描述纹理贴图的坐标自定义顶点UVgeometry.attributes.uv…