简介
本项目是以matlab为主语言并设计GUI界面的一款简易美图秀秀,包含基础的图像处理和一些常见美颜算法
对于一些matlab较难实现的算法采用C++或python来实现
⭐️ github地址:https://github.com/mibbp/MeituShow
里面有我完整的代码,你想直接运行记得看readme配置一下环境,本博客更多的是讲解原理
具体功能包括:
- 增加图像亮度,对比度
- 美白人像
- 采用双边滤波算法磨皮
- 采用液化算法并用dlib提取特征点实现瘦脸
- 基于液化算法并用dlib提取特征点实现大眼
- 采用dlib提取特征点,采用Andrew求凸包并用BFS实现唇彩
- 采用SRCNN超分辨率算法实现提升照片像素
- 采用Beauty-GAN算法实现彩妆迁移
磨皮算法
先说最简单的磨皮算法,磨皮其实就是把人脸上不光滑的东西磨掉,那这些不光滑的东西其实就是噪点,所以可以很自然的想到运用一些滤波算法去做磨皮处理
均值滤波
均值滤波无疑是最简单的,他的想法就是通过领域加权来达到滤波的目的,领域通常是指以自己为中心的周围八个元素,其实也就是一个 3 × 3 3 \times 3 3×3的卷积核或者说滤波器,八领域如下图所示
因为正常情况下都是照片上有噪点,也就是噪点数量远小于有效像素数量,而不是噪点上有照片,所以一个像素点周围八个元素一定是有效像素更多,那计算周围八个连带自己的总和除以9产生的新值就可以作为滤波后的像素值,因为有效像素比噪点多所以计算的均值一定是有效像素占比更大,然后遍历每个像素点都对他求一个八邻域均值,整体过程其实就是个卷积
高斯滤波
均值滤波的加权其实就是大家都是1,所以算下来的结果就是平均值,看上去很公平,但是实际上并不是,对于离目标像素点理应权重更大(明明是我先来的),因为在一个低频区域(也就是联通区域)离得越近那我们应该更相似,那么距离我越近提供的有效信息也就越多,所以他的权重也应该更大,离的越远权重应该越低,而这很明显符合高斯函数的特征,而且人们认为大多数图片噪声是符合高斯分布的(就是正态分布,由中心极限定理表明,一个随机变量如果是由大量微小的、独立的随机因素的叠加结果,那么这个变量一般都可以认为服从正态分布),所以我们把滤波器的值改一下,改成基于距离的高斯函数加权
高斯函数(正态分布函数)如下所示
G
(
x
,
y
)
=
1
2
π
σ
2
e
−
x
2
+
y
2
2
σ
2
G(x,y) = \frac {1}{2\pi\sigma^2}e^{- \frac{x^2+y^2}{2\sigma^2}}
G(x,y)=2πσ21e−2σ2x2+y2
假设中心点坐标为
(
0
,
0
)
(0,0)
(0,0),那么他的八邻域就分别为
然后计算出距离套高斯函数,这里设 σ = 1.5 \sigma = 1.5 σ=1.5,则模糊半径为1的权重矩阵为
但是还得进行归一化,也就是让他们的权重之和为1,因为得保证他们和其他处理处于同一量级,对于上面的值分别处以0.4787147就好了
但你实际写代码很简单matlab这些都有自带实现好的,可以看看高斯滤波的效果
运行结果
磨皮效果还凑合
双边滤波
虽然高斯滤波效果还凑合但是他有个致命问题那就是他会模糊五官,这是我们不想看到的,为了不模糊五官我们可以采用保边滤波算法,其中双边滤波就是最经典简单的保边滤波了
先说为什么高斯滤波会模糊五官,因为它只关注位置信息,高斯滤波认为距离中心点越近权重越大,这种只关注距离的思想在某些情况是可行的,比如在低频平坦区域,距离越近的像素肯定分布越相近,但是在高频边缘区域,这种方法就会适得其反,会损失掉有用的边缘信息,这个时候就要用到保边滤波算法
想深入了解双边滤波算法原理的我建议看这两篇论文,我这里只做通俗的讲解
-
Fast O(1) Bilateral Filtering Using Trigonometric Range Kernels
-
Fast Adaptive Bilateral Filtering
算法原理
我们可以很容易发现五官的边界和皮肤有很明显的区别(不然你可以看不出这个人有鼻子有眼的),也就是说在五官和皮肤的交界处一定会有极大的像素值差,原本的高斯滤波是只以距离差为变量,那我们在此基础上再加个像素值差,也就是说距离中心点距离越近权重越高,但是和中心点的像素值差值越大权重越小,且像素值差值的影响要大于距离值
于是就设计出双边滤波的一个公式
g
(
p
)
=
η
(
p
)
−
1
∑
q
∈
Ω
G
σ
s
(
∥
p
−
q
∥
)
G
σ
r
(
∣
F
(
p
)
−
F
(
q
)
∣
)
F
(
q
)
η
(
p
)
=
∑
q
∈
Ω
G
σ
s
(
∥
p
−
q
∥
)
G
σ
r
(
∣
F
(
p
)
−
F
(
q
)
∣
)
G
σ
s
(
∥
p
−
q
∥
)
=
e
−
(
i
−
m
)
2
+
(
j
−
n
)
2
2
σ
s
2
G
σ
r
(
∣
F
(
p
)
−
F
(
q
)
∣
)
=
e
−
[
F
(
i
,
j
)
−
F
(
m
,
n
)
]
2
2
σ
r
2
p
,
q
表示像素点,
F
(
p
)
表示该点像素值
Ω
表示图片
,
(
i
,
j
)
为卷积核中心
(
m
,
n
)
则表示卷积核中心周围其他值
g(p) = \eta(p)^{-1}\sum_{q\in\Omega}G_{\sigma_s}(\Vert p-q\Vert) G_{\sigma_r}(\vert F(p)-F(q)\vert)F(q) \\ \eta(p) = \sum_{q\in\Omega}G_{\sigma_s}(\Vert p-q\Vert) G_{\sigma_r}(\vert F(p)-F(q)\vert) \\ G_{\sigma_s}(\Vert p-q\Vert) = e^{-\frac {(i-m)^2+(j-n)^2} {2\sigma_s^2} } \\ G_{\sigma_r}(\vert F(p)-F(q)\vert) = e^{-\frac {[F(i,j)-F(m,n)]^2} {2\sigma_r2} } \\ p,q表示像素点,F(p)表示该点像素值 \\ \Omega 表示图片,(i,j)为卷积核中心 \\ (m,n)则表示卷积核中心周围其他值
g(p)=η(p)−1q∈Ω∑Gσs(∥p−q∥)Gσr(∣F(p)−F(q)∣)F(q)η(p)=q∈Ω∑Gσs(∥p−q∥)Gσr(∣F(p)−F(q)∣)Gσs(∥p−q∥)=e−2σs2(i−m)2+(j−n)2Gσr(∣F(p)−F(q)∣)=e−2σr2[F(i,j)−F(m,n)]2p,q表示像素点,F(p)表示该点像素值Ω表示图片,(i,j)为卷积核中心(m,n)则表示卷积核中心周围其他值
这个公式看着很吓人其实真的很简单,但其实就是俩高斯函数的叠加一个是以距离为变量一个是以像素差值为变量,并做卷积求和, η ( p ) − 1 \eta(p)^{-1} η(p)−1是用来做归一化处理的, G σ s ( ∥ p − q ∥ ) G_{\sigma_s}(\Vert p-q\Vert) Gσs(∥p−q∥) 就是以像素值为变量的高斯函数, G σ r ( ∣ F ( p ) − F ( q ) ∣ ) G_{\sigma_r}(\vert F(p)-F(q)\vert) Gσr(∣F(p)−F(q)∣) 则是以像素差值为变量的高斯函数,具体分析可以看论文或者私聊问我文章来源:https://www.toymoban.com/news/detail-501308.html
代码
% 双边滤波器
function results = B_filter(~,Img,tempsize,sigma0,sigma1)
gauss = fspecial('gauss',2*tempsize+1,sigma0);
[m,n] = size(Img);
% tempsize为卷积核大小
for i = 1+ tempsize : m - tempsize
for j = 1+ tempsize : n - tempsize
% 提取处理区域得到梯度敏感矩阵
% 得到灰度差值矩阵,并用高斯函数处理为灰度差越大则最终数值越小的权重矩阵
temp = abs(Img(i - tempsize:i + tempsize,j - tempsize:j + tempsize) - Img(i,j));
temp = exp(-temp.^2/(2*sigma1^2));
%将权重矩阵与高斯滤波器相乘,得到双边滤波器,并将权值和化为一
filter = gauss.*temp;
filter = filter/sum(filter(:));
% 卷积求和
Img(i,j) = sum(sum((Img(i - tempsize:i + tempsize,j - tempsize:j + tempsize).*filter)));
end
end
results = Img;
end
% 双边滤波函数
function results = BF(app,I)
tempsize = round(app.Slider_4.Value); %控制卷积核大小的参数
sigma1 = round(app.Slider_5.Value); %控制标准差
sigma2 = app.Slider_6.Value; %控制灰度的敏感性,越大的灰度差,权重越小
%模板补零,便于卷积操作,不然会使得图片区域出现黑边
img = double(padarray(I,[tempsize,tempsize],0))/255;
imgr = img(:,:,1);
imgg = img(:,:,2);
imgb = img(:,:,3);
img(:,:,1) = app.B_filter(imgr,tempsize,sigma1,sigma2);
img(:,:,2) = app.B_filter(imgg,tempsize,sigma1,sigma2);
img(:,:,3) = app.B_filter(imgb,tempsize,sigma1,sigma2);
results = img;
end
效果对比
双边滤波
高斯滤波
文章来源地址https://www.toymoban.com/news/detail-501308.html
到了这里,关于数字图像处理—美图秀秀:磨皮算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!