数字图像处理—美图秀秀:磨皮算法

本项目是以Matlab为主语言设计GUI界面的简易美图工具,包含图像处理与美颜算法。博客重点讲解磨皮算法,介绍了均值滤波、高斯滤波和双边滤波的原理,指出高斯滤波会模糊五官,而双边滤波作为保边滤波可避免此问题,还给出双边滤波公式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

本项目是以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的卷积核或者说滤波器,八领域如下图所示

image.png

因为正常情况下都是照片上有噪点,也就是噪点数量远小于有效像素数量,而不是噪点上有照片,所以一个像素点周围八个元素一定是有效像素更多,那计算周围八个连带自己的总和除以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πσ21e2σ2x2+y2
假设中心点坐标为 ( 0 , 0 ) (0,0) (0,0),那么他的八邻域就分别为

参考来源:(https://blog.csdn.net/nima1994/article/details/79776802)

然后计算出距离套高斯函数,这里设 σ = 1.5 \sigma = 1.5 σ=1.5,则模糊半径为1的权重矩阵为

参考来源:(https://blog.csdn.net/nima1994/article/details/79776802)

但是还得进行归一化,也就是让他们的权重之和为1,因为得保证他们和其他处理处于同一量级,对于上面的值分别处以0.4787147就好了

参考来源:(https://blog.csdn.net/nima1994/article/details/79776802)

但你实际写代码很简单matlab这些都有自带实现好的,可以看看高斯滤波的效果

运行结果

image.png

磨皮效果还凑合

双边滤波

虽然高斯滤波效果还凑合但是他有个致命问题那就是他会模糊五官,这是我们不想看到的,为了不模糊五官我们可以采用保边滤波算法,其中双边滤波就是最经典简单的保边滤波了

先说为什么高斯滤波会模糊五官,因为它只关注位置信息,高斯滤波认为距离中心点越近权重越大,这种只关注距离的思想在某些情况是可行的,比如在低频平坦区域,距离越近的像素肯定分布越相近,但是在高频边缘区域,这种方法就会适得其反,会损失掉有用的边缘信息,这个时候就要用到保边滤波算法

想深入了解双边滤波算法原理的我建议看这两篇论文,我这里只做通俗的讲解

算法原理

我们可以很容易发现五官的边界和皮肤有很明显的区别(不然你可以看不出这个人有鼻子有眼的),也就是说在五官和皮肤的交界处一定会有极大的像素值差,原本的高斯滤波是只以距离差为变量,那我们在此基础上再加个像素值差,也就是说距离中心点距离越近权重越高,但是和中心点的像素值差值越大权重越小,且像素值差值的影响要大于距离值

于是就设计出双边滤波的一个公式
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(pq)Gσr(F(p)F(q))F(q)η(p)=qΩGσs(pq)Gσr(F(p)F(q))Gσs(pq)=e2σs2(im)2+(jn)2Gσr(F(p)F(q))=e2σ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(pq) 就是以像素值为变量的高斯函数, G σ r ( ∣ F ( p ) − F ( q ) ∣ ) G_{\sigma_r}(\vert F(p)-F(q)\vert) Gσr(F(p)F(q)) 则是以像素差值为变量的高斯函数,具体分析可以看论文或者私聊问我

代码

% 双边滤波器
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

效果对比

双边滤波
双边滤波
高斯滤波
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值