matlab去除图片中的阴影(用高斯模糊估计阴影模式)

1、思路

2、阴影模式的估计方法

3、代码实现

3.1、通过现成的函数来构造高斯滤波器

3.2、通过原理构建高斯低通滤波器


1、思路

由于光照等原因造成的图片存在阴影且影响视觉效果的情况,带阴影的图像可以表示为:

g(x,y)=f(x,y)s(x,y)

其中,g(x,y)是最终的图像,f(x,y)s(x,y)分别是没有受到影响的原图像和阴影图像(对原图像造成干扰)。由此可见,只要想办法去除这个阴影模式就可以恢复原图像(原图除以阴影模式,一种形态学方法)。

首先需要回顾一下图像的加减乘除的作用:

图像加减乘除作用
一般用于去除均值为零的噪声
-一般用于体现出两幅图像的差异/减法降噪等
.*一般用于实现阴影模式处理(屏蔽一部份区域)
./一般用于去除阴影模式

从上表可以看出,我们这次需要用到图像的乘除法。

2、阴影模式的估计方法

阴影模式的一种估计方法是通过模糊化的方法或的图像背景,用该背景作为阴影模式。

所谓的模糊化,一般是用来降噪的,以模糊为代价来消除噪声,所以更常见的叫法应该是滤波。

 对于类似这样一幅图片,首先构造一个低通滤波器(用来提取阴影背景),然后计算出阴影模式,并根据上面给出的公式利用乘除法求出原图。

高斯低通滤波器的模糊效果更平滑,且二维的高斯滤波器可以拆分为两个一维的高斯滤波器(暂时知道就行)在一些情况下可以大幅减少运行时间。

滤波器处理过程实际上就是一个相乘再相加的过程:原图像是个大矩阵,滤波器是个小矩阵,小矩阵在大矩阵上相对移动,每移动一次得到一个卷积结果,等原图像所有像素点处理完成后,利用处理结果构造一个新的图像(阴影模式的估计)。

G(r)=Ke^{-\frac{r^{2}}{2\sigma^{2} }}

这里的K为常数,因为只需要用到高斯函数的钟形特性,r为与均值的差,sigma为标准差。需要注意的是:卷积核(就是之前说的小矩阵,也就是我们要构造的低通滤波器)的大小靠近6*sigma,取奇数。

3、代码实现

3.1、通过现成的函数来构造高斯滤波器

clc
clear
close
I = imread('C:\Users\含笑韭泉\Desktop\图片1.png');
if length(size(I))==3
    I = rgb2gray(I);
end
% 这一段增加了源图像的边缘(补零)
m = 3;
sem = floor(m/2);
I = im2double(I);
a = zeros(size(I,1)+m-1,size(I,2)+m-1);
a(sem+1:size(I,1)+sem,sem+1:size(I,2)+sem) = I;
I = a;
% 这一段增加了源图像的边缘(补零)
subplot(1,3,1)
imshow(I);
B = imgaussfilt(I,87,"FilterSize",513,"FilterDomain",'spatial');    %自动创建高斯滤波器
subplot(1,3,2)
imshow(B);
C = I ./ B;
subplot(1,3,3)
imshow(C);

*卷积操作实际上就是一系列相乘求和的过程,卷积核(矩阵)在图像的每一行每一列扫过,每个像素点的值等于卷积核与当前像素点区域(矩阵,和卷积核一样大)的各个元素乘积求和,每个新像素值要乘以一个缩放系数(卷积核内所有元素的和的倒数)。*


其中,这里的imgaussfilt函数可以通过在命令行窗口输入“doc imgaussfilt”来查看。

B= imgaussfilt(A)

使用标准差为 0.5 的二维高斯平滑核对图像 A 进行滤波,并在 B 中返回滤波后的图像。
B = imgaussfilt(A,sigma)使用由 sigma 指定标准差的二维高斯平滑核对图像 A 进行滤波。
B = imgaussfilt(___,Name,Value)使用名称-值对组参数来控制滤波的各个方面。

 

可以看出,起到了较好的效果,去除了背景阴影。

3.2、通过原理构建高斯低通滤波器

之前提到了二维高斯低通滤波器可以用两个一维的代替,原因是:该卷积具有交换律,多阶滤波可由多级滤波来实现。

clc
clear
close
I = imread('C:\Users\含笑韭泉\Desktop\图片1.png');
if length(size(I))==3
    I = rgb2gray(I);
end
I = im2double(I);
I0 = I;
[I_row,I_col] = size(I);

m = 513; %大小,这里的值越大模糊效果越好,但是计算量越大
K = 1; %系数,无所谓
s = floor(m/6);   %标准差
sem = floor(m/2);
G = zeros(1,m);    %行分量高斯核
for i = 1:m
    r = i - ceil(m/2);
    G(i) = K * exp(-r^2/(2*s^2));
end
subplot(2,2,1)
imshow(I);
title("原图");
leftSide = zeros(I_row,sem);    %扩展原图像,方便计算
rightSide = zeros(I_row,sem);
I_enlargeLR = [leftSide,I,rightSide];
% 按行进行高斯低通滤波
for i = 1:I_row
    for j = 1 + sem:I_col + sem
        I(i,j-sem) = sum(G .* I_enlargeLR(i,j-sem:j+sem)) / sum(G); %卷积计算结束要进行归一化
    end
end
subplot(2,2,2)
imshow(I);
title("一次(横向)卷积");
upSide = zeros(sem,I_col);
downSide = zeros(sem,I_col);
I_enlargeUD = [upSide;I;downSide];
% 按列进行高斯低通滤波
for i = 1 + sem:I_row + sem
    for j = 1:I_col
        % 这里的G没有转置和没有使用点乘是对应的
        I(i-sem,j) = G * I_enlargeUD(i-sem:i+sem,j) / sum(G);
    end
end
subplot(2,2,3)
imshow(I);
title("二次(纵向)卷积");
subplot(2,2,4)
Ie = I0./(I);   % 原图除以阴影模式
imshow(Ie);
title("恢复图");

结果表明,效果同样可以。但是,通用性还有待研究,后续学到了再拿出来讨论,也欢迎各位一起学习进步,一起讨论

  • 9
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值