11 S整数小波分解图像(matlab程序)

1.简述

学习目标:  非标准小波分解(用S整数变换)

      小波分解过程:读取加入噪声后的图片后,数据即是高度*宽度个数据点。对此矩阵数据要做二维离散小波分解,二维小波变换和一维小波变换的区别从原理上来说就是一和二的关系。首先对数据做行分解,写入循环,有多少行就做多少次小波分解。对于每一行的数据来说,做小波分解就是一维的,而一维小波分解就是咱们要写的程序中的基石。选择小波,以Haar小波为例,也叫db1,用函数调用此小波,将咱们的数据(就是之前的行数据)先与高通做卷积得出高频系数,这里建议卷积过程别手写,计算太慢了,计算函数直接调用即可。然后使用下采样得出高频系数cD,再与低通做卷积加下采样得出低频系数cA。这里说明一下由于是下采样,所以得到的每个系数矩阵是原矩阵的一半大小。最后将低频系数cA和高频系数cD组成系数矩阵。这是一次小波分解,如果需要二次小波分解,则是按照小波分解定义,将第一次小波分解的低频系数cA作为第二次分解的输入重复卷积和采样操作,再得出新的cA、cD,编程写循环即可。回到咱们每一行都做一维小波分解,将做完行分解后得到的新矩阵再对每一列进行列分解,按照同样的道理将系数组合起来得到最终的矩阵(这里注意一下行分解的矩阵和列分解的矩阵在组合系数时的行列转换问题)。最终的矩阵分为四块,左上角是低频系数cA,其余三块分别是高频系数cH、cV、cD,具体形式是[cA,cH;cV,cD]。别忘了一维小波分解咱们能做好几次,二维也是,用同样的道理,低频系数cA进入下一层,还是先做行分解再做列分解然后出结果,也是写循环解决。到此小波分解结束。

整数小波S变换对图像进行分解和重构

题目用整数小波的S变换对256*256 Lena灰度图像进行非标准方法的3级分解与重构。

 

本案例的意义在于通过实验体会到整数小波变换。案例并不是直接利用MATLAB工具箱中的已有小波函数对图象进行整数小波分解,而是用下面的分解公式进行小波分解和重构。

 

进行非标准小波分解,交替进行3次行变换和3次列变换。

程序对每次变换后的结果都保存为位图文件,运行后可以在程序所在路径下看到保存的6个分解位图文件和6个重构位图文件。最后在一个图像中显示每次分解后的图像,便于对比。

 

实现方法:编写S变换的分解和重构子程序,分别对图像数据进行一次行列分解和列行重构,程序返回该次变换后的行列矩阵,在主程序中可以连续三次调用行列变换,即完成对原始图像的3级分解和重构,这里的变换是完全可逆的,也就是能够完全恢复原图像数据。通过对比3次重构后返回的数据与原图像数据后发现它们完全相同。

主要用的MATLAB工具函数有:

imread( )---------读取图像数据,为uint8类型,需变为double类型才能进行各种运算

imwrite()---------用于保存图像,这里用它来保存每一级变换后的图像

image( )----------显示图像,需要给出色谱表colormap,这里是灰度图,用colormap =gray(256)即可

subplot( )--------用于在一个窗口下绘制多个图像,在这里用于输出变换后的图像,以便对比。

更详细的内容请参考函数文件SDecompose.m和SRecompose.m,分别是分解和重构图像的函数,main.m是演示主程序。

注意事项:在首次成功后发现原图像数据和重构数据总有误差,但是根据S整数变换的可逆性,应该可以完全重构原始数据,在排除了是程序变换运算错误后,发现读出图像数据类型是uint8后,估计是该类型运算出错,上网搜索后终于找到症结所在:由于MATLAB读出的图像数据保存的是uint8类型(单字节0~255),它不能直接参与运算,在变为double类型后才可以进行运算。改造程序后,发现果然如此,此时原始数据和重构数据完全相同。

2.代码

主程序:
filename = input('Input the image file name: (size: 256×256 gray image)\nor press d key for default image:lena.bmp > ', 's');
if filename == 'd'
    filename = 'lena.bmp';
end
im = imread(filename);
de = SDecompose(im, 256);
input('Press any key to recompose the image ...'); 
re = SRecompose(de, 256);

 

子程序:

function imde = SDecompose( imMat, dim )
%%  非标准小波变换,用S整数变换3级分解图像数据,
% 输入参数imMat为原始256×256灰度图像数据方阵,
% imde为3级分解后的图像矩阵,分解灰度图
% S变换方法:分解式 Dj-1, k = Sj, 2k +1 - Sj, 2k;Sj-1, k =     Sj, 2k + [Dj-1, k / 2] 
% 重构式 Sj, 2k = Sj-1, k - [Dj-1, k / 2] Sj, 2k +1 = Dj-1, k + Sj, 2k
% 其中 S为对应图象数据
% dim = 256;
imMat = double(imMat);
map = gray(256);
subplot(4, 4, 1); image(imMat);colormap(map); title('原 图 像'); axis square; axis off;
% 对每一行和列交替进行第一次S分解变换
[imder, imdec] = decompose(imMat, dim);
% imder
% imdec
imgray = mat2gray(imder);          % 转为灰度矩阵
imwrite(imgray, 'imgraylr.bmp');   % 保存1次列变换后的灰度图
subplot(4, 4, 2); image(imder);colormap(map); title('1次行分解'); axis square; axis off;
imgray = mat2gray(imdec);
imwrite(imgray, 'imgray1c.bmp');
subplot(4, 4, 6); image(imdec);colormap(map); title('1次列分解'); axis square; axis off;

%%   对每一行和列交替进行第二次S分解变换
[imder, imdec] = decompose(imdec, dim/2);
imgray = mat2gray(imder);        % 转为灰度矩阵
imwrite(imgray, 'imgray2r.bmp'); % 保存2次行变换后的灰度图
subplot(4, 4, 7); image(imder);colormap(map); title('2次行分解'); axis square; axis off;
imgray = mat2gray(imdec);
imwrite(imgray, 'imgray2c.bmp');
%%     显示2次列变换后的灰度图
subplot(4, 4, 11); image(imdec);colormap(map); title('2次列分解'); axis square; axis off;

%%      对每一行和列交替进行第三次S分解变换
[imder, imdec] = decompose(imdec,dim/4);
imde = imdec;
imgray = mat2gray(imder);        % 转为灰度矩阵
imwrite(imgray, 'imgray3r.bmp'); % 保存3次行变换后的灰度图
subplot(4, 4, 12); image(imder);colormap(map); title('3次行分解'); axis square; axis off;

imgray = mat2gray(imdec);
imwrite(imgray, 'imgray3c.bmp');
subplot(4, 4, 16); image(imdec);colormap(map); title('3次列分解'); axis square; axis off;

%-----------------------------子程序decompose---------------------------------
function [imder, imdec] = decompose(imMat, dim)
%%   对每一行和列交替进行一次S分解变换, dim是维数
imder = imMat;
imdec = imMat;
for i = 1:dim                                                               % 对每一行进行S分解变换
    for j = 1:2:dim  
        imder(i, dim/2+(j+1)/2) = imMat(i, j+1) - imMat(i, j);              % 计算该行后半部分即Dj-1,k
        imder(i, (j+1)/2) = imMat(i, j) + floor(imder(i, dim/2+(j+1)/2)/2); % 计算该行前半部分即Sj-1,k
    end
end
%%  列变换
for i = 1:dim                                                             % 对每一列进行S分解变换
    for j = 1:2:dim
        imdec(dim/2+(j+1)/2, i) = imder(j+1, i) - imder(j, i); 
        imdec((j+1)/2, i) = imder(j, i) + floor(imdec(dim/2+(j+1)/2, i)/2);
    end
end

 

3.运行结果

a1a02d1792244323ba8cb06e4564b576.png

 

3级分解效果图

                                                                      

 

5cd4ad72997445c68970f868fca4aa19.png

 

3级重构效果图

 

                          

 

 

 

 

 

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

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

相关文章

分别基于红黑树、timefd、多级时间轮实现定时器

文章目录 一、定时器的应用二、定时器的触发方式2.1 网络事件和定时事件在一个线程中处理2.2 二、定时器的设计2.1 接口设计2.2 数据结构设计2.2.1 红黑树2.2.3 最小堆2.2.4 时间轮 三、利用红黑树实现定时器3.1 数据结构3.2 接口实现3.2.1 初始化定时器3.2.2 添加定时器3.2.3 …

dubbo入门

Dubbo概述 官网: https://dubbo.apache.org Dubbo快速入门 1 安装zk 参考 https://blog.csdn.net/qq_34914039/article/details/131614771 2 实现步骤

【Linux系统编程】20.程序、进程、CPU和MMU、PCB

目录 程序 进程 CPU和MMU PCB 程序 编译好的二进制文件,存在磁盘上,只占用磁盘资源。 进程 进程是活跃的程序,占用系统资源,在内存中执行。程序运行起来,产生一个进程。 程序类似于剧本,进程类似于一场…

Docker学习笔记16

在生产环境中使用Docker,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享。 容器管理数据有两种方式: 1)数据卷:容器内数据直接映射到本地主机环境; 2)数据卷容器:…

STM32实战项目—楼宇人员计数系统

本文项目比较简单,目的是介绍一下红外对管的使用,程序设计也比较简单。因此,博主并没有将程序工程上传资源,如果有需要的话可以私信。 文章目录 一、任务要求二、实现方法2.1 红外对管简介2.2 进出人员检测 三、程序设计3.1 红外对…

Jenkins基础介绍以及docker安装Jenkins

Jenkins基础介绍以及docker安装Jenkins 什么是Jenkins? Jenkins是一个可扩展的持续集成引擎 持续集成就是通常说的CI(Continues Integration) 每次集成都通过自动化的构建(包括编译,发布,自动化测试&am…

基于simulink仿真车道偏离警告系统(附源码)

一、前言 此示例演示如何在视频序列中检测和跟踪道路车道标记,并在驾驶员穿过车道时通知驾驶员。该示例说明了如何使用霍夫变换、霍夫线和卡尔曼滤波器模块来创建线检测和跟踪算法。该示例使用以下步骤实现此算法:1) 检测当前视频帧中的车道…

Zabbix 6.0 介绍及部署

目录 一、Zabbix 6.0 介绍1. 简介2. **利用一个优秀的监控软件带来的好处**3. **zabbix 6.0 的功能组件**4.zabbix 监控原理 二、Zabbix 6.0 部署 一、Zabbix 6.0 介绍 1. 简介 Zabbix 是由 Alexei Vladishev 创建,目前是由 Zabbix SIA 在持续开发和提供支持。zab…

python 实现简易的学员管理系统

文章目录 前言基本思路需求实现1.实现菜单的功能2.提示用户输入需要进行的操作,并执行相关操作3.具体函数功能的实现增加学员信息显示所有学员信息删除学员信息修改学员信息查询学员信息 整体代码展示 前言 前面我们已经学习了 python 的输入输出、条件语句、循环、…

Redis - 一篇讲解根据 Key 前缀统计分析内存占用

问题描述 今天遇到一个 Redis 内存打挂了的问题,想看看哪个前缀 Key 占用内存比较大?! 原因分析 我们都知道如果直接用 Keys 参数去做统计很危险,而且也只能统计数量,当然也可以排序去前几名的占用内存 Key 对应的大…

逆转乾坤,反转字符串

本篇博客会讲解力扣“344. 反转字符串”的解题思路,这是题目链接。 这是一道经典题目了。解题思路是:双下标,left指向最左边的字符,right指向最右边的字符,交换2个字符,left向右挪动一格,right向…

细谈容器化技术实现原理--以Docker为例

目录 一、Docker解决了什么 二、容器的发展过程 三、容器基础 3.1. 容器实现的原理: ⚠️原理详解: 3.1.1. Namespace 3.1.2. Cgroups 3.1.3. chroot 四、Volume 4.1. Docker是如何做到把一个宿主机上的目录或者文件,挂载到容器里面…