关于MATLAB中对除零错误的特殊处理中eps和sqrt(eps)的区别

        在MATLAB的矩阵运算中,我们难免遇到除数为0的情况,一般来说,我们会选择将其置为eps或者sqrt(eps),但在官方文档中更多的是置为sqrt(eps),如维纳滤波器去卷积函数deonvwnr、有约束最小二乘去卷积函数deconvreg、Lucy-Richarson迭代法去卷积deconvlucy都有对0处理的代码块。

deconvwnr部分代码展示:

 deconvreg部分代码展示:

 deconvlucy部分代码展示:

         一般来说,使用eps和sqrt(eps)是没有区别的,或者说觉得理所当然没有区别,都是非常小的数。实际上,如果在一个矩阵中,0不是成片出现的情况,也就是说在矩阵中偶尔出现一个0,使用eps和sqrt(eps)是没有区别的,但是如果矩阵中有一大片0出现,那么使用eps和sqrt(eps)处理的结果可能会完全不一样。

        这是因为在傅里叶变换和傅里叶逆变换中,得到的很小的数可能会有正有负,当0聚集的时候,即使加上eps,这一片0得到的结果仍然会有正有负。虽然是小数,但是在正负波动会给后续傅里叶变换的处理带来错误计算。

        例子:

clear
% 以运动模糊的点扩散函数为例
h = fspecial('motion',30,45);
H = psf2otf(h,[513,513]);
% 生成周边为0,中心为1的权重矩阵
% 其目的是产生聚集的0(边缘)
w = zeros(513,513);
w(20:end-19,20:end-19) = 1;
r = real(ifft2(H.*fft2(w))) + sqrt(eps);
% r = real(ifft2(H.*fft2(w))) + eps;

        当使用的是sqrt(eps)时,也就是不注释的那一行,得到的边缘部分的值如图:

        非常整齐、全为正的小数,如果运行最后一行注释的代码 ,将会得到:

         有正有负的小数。

        它可能会为后续的计算带来错误。

        更多试验发现是:matlab中快速傅里叶变换时,如果矩阵的边长不是2的整数次幂,才会出现这样的情况。

        使用eps带来恶劣影响的例子:

      (其中图片自己随便导入一张就好)

clc
clear
close all
I = rgb2gray(im2double(imread('图片.png')));
I = im2double(I);
subplot(1,3,1),imshow(I);
LEN = 30;
THETA = 45;
h = fspecial('motion',30,45);
img_motion = imfilter(I,h,'circular');
%添加噪声
noise_var = 0.001;
img_motion = imnoise(img_motion,'gaussian',0,noise_var);
subplot(1,3,2),imshow(img_motion,[0,1])
w = zeros(size(img_motion));
w(20:end-19,20:end-19) = 1;
img_recov = deconvlucy(img_motion,h,10,sqrt(noise_var),w);
subplot(1,3,3),imshow(img_recov)

 运行结果:

(左边是原图,中间是模糊图,右边是复原图)

 当我们修改官方文档deconvlucy中的sqrt(eps)为eps后再运行代码:

         则会得到如此不正确的图:

        总的来说,对包含0元素多的矩阵进行处理的时候,我们可能需要一个比eps更大的一个小数,这时sqrt(eps)可以是一个很好的选择。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值