数字图像处理-美图秀秀:美白算法

简介

本项目是以matlab为主语言并设计GUI界面的一款简易美图秀秀,包含基础的图像处理和一些常见美颜算法

对于一些matlab较难实现的算法采用C++或python来实现

⭐️ github地址:https://github.com/mibbp/MeituShow

里面有我完整的代码,你想直接运行记得看readme配置一下环境,本博客更多的是讲解原理

具体功能包括:

  • 增加图像亮度,对比度
  • 美白人像
  • 采用双边滤波算法磨皮
  • 采用液化算法并用dlib提取特征点实现瘦脸
  • 基于液化算法并用dlib提取特征点实现大眼
  • 采用dlib提取特征点,采用Andrew求凸包并用BFS实现唇彩
  • 采用SRCNN超分辨率算法实现提升照片像素
  • 采用Beauty-GAN算法实现彩妆迁移

美白算法

这个很简单,网上资源也很多,这里讲一下3A算法之一的白平衡(AWB)

YCbCr空间

YUV空间是以前为了解决同时兼容黑白和彩色电视机提出来的,Y指亮度,UV代表颜色分量,黑白电视只显示Y亮度通道就行,而彩色电视则加入颜色分量就行,这里的YCbCr就是如此,其中Y表示亮度,Cb,Cr表示蓝色和红色分量,RGB颜色空间可以和YCbCr互转乘一个矩阵就好了

这里之所以采用YCbCr空间是因为RGB空间里人脸的肤色受亮度影响相当大,所以肤色点很难从非肤色点中分离出来,也就是说在此空间经过处理后,肤色点是离散的点,中间嵌有很多非肤色,这为肤色区域标定(人脸标定、眼睛等)带来了难题。如果把RGB转为YCrCb空间的话,可以忽略Y(亮度)的影响,因为该空间受亮度影响很小,肤色会产生很好的类聚。这样就把三维的空间降为二维的CrCb,肤色点会形成一定得形状,如:人脸的话会看到一个人脸的区域,手臂的话会看到一条手臂的形态,对处理模式识别很有好处,根据经验某点的CrCb值满足:133≤Cr≤173,77≤Cb≤127 那么该点被认为是肤色点,其他的就为非肤色点。

灰色世界算法

灰色世界假设:任意一副图像,当它有足够的色彩变化,则它的RGB分量的均值会趋于相等

这是一个假设,灰色世界算法就是基于这个假设的,写起来也是真的简单
∵ R m e a n = G m e a n = B m e a n 以 G 为基准算法 R , B 的增益 ∴ R g a i n = G m e a n R m e a n ∴ B g a i n = G m e a n B m e a n ∴ R ′ = R ⋅ R g a i n ∴ B ′ = B ⋅ B g a i n \because R_{mean} = G_{mean} = B_{mean} \\ 以G为基准算法R,B的增益 \\ \therefore R_{gain} = \frac{G_{mean}}{R_{mean}} \\ \therefore B_{gain} = \frac{G_{mean}}{B_{mean}} \\ \therefore R' = R\cdot R_{gain} \\ \therefore B' = B\cdot B_{gain} Rmean=Gmean=BmeanG为基准算法R,B的增益Rgain=RmeanGmeanBgain=BmeanGmeanR=RRgainB=BBgain

完美反射算法

完美反射算法基于这样一种假设,一幅图像中最亮的像素相当于物体有光泽或镜面上的点,它传达了很多关于场景照明条件的信息。如果景物中有纯白的部分,那么就可以直接从这些像素中提取出光源信息。因为镜面或有光泽的平面本身不吸收光线,所以其反射的颜色即为光源的真实颜色,这是因为镜面或有光泽的平面的反射比函数在很长的一段波长范围内是保持不变的。完美反射法就是利用用这种特性来对图像进行调整。算法执行时,检测图像中亮度最高的像素并且将它作为参考白点。基于这种思想的方法都被称为是完美反射法也称镜面法。
R g a i n = m a x ( R m a x , G m a x , B m a x ) R m a x G g a i n = m a x ( R m a x , G m a x , B m a x ) G m a x B g a i n = m a x ( R m a x , G m a x , B m a x ) B m a x R_{gain} = \frac{max(R_{max},G_{max},B_{max})}{R_{max}} \\ G_{gain} = \frac{max(R_{max},G_{max},B_{max})}{G_{max}} \\ B_{gain} = \frac{max(R_{max},G_{max},B_{max})}{B_{max}} Rgain=Rmaxmax(Rmax,Gmax,Bmax)Ggain=Gmaxmax(Rmax,Gmax,Bmax)Bgain=Bmaxmax(Rmax,Gmax,Bmax)

动态阈值法

  • 将图像从RGB空间变换到YCrCb空间

[ Y C b C r ] = [ 0.257 0.564 0.098 − 0.148 − 0.291 0.439 0.439 − 0.368 − 0.071 ] [ R G B ] + [ 16 128 128 ] \begin{equation} \begin{bmatrix} Y \\ C_b \\ C_r \end{bmatrix} = \begin{bmatrix} 0.257 & 0.564 & 0.098 \\ -0.148 & -0.291 & 0.439 \\ 0.439 & -0.368 & -0.071 \end{bmatrix} \begin{bmatrix} R \\ G \\ B \end{bmatrix} + \begin{bmatrix} 16 \\ 128 \\ 128 \end{bmatrix} \end{equation} YCbCr = 0.2570.1480.4390.5640.2910.3680.0980.4390.071 RGB + 16128128

  • 白点检测:为了增强算法的鲁棒性,将图像分为12部分

    • 计算每个区域的 C r , C b C_r,C_b CrCb的均值 M r , M b M_r,M_b MrMb,N为每块区域的像素个数:
      M r = ∑ C r ( i , j ) N , M b = ∑ C b ( i , j ) N M_r = \frac {\sum C_r(i,j)}{N},M_b = \frac {\sum C_b(i,j)}{N} Mr=NCr(i,j),Mb=NCb(i,j)

    • 计算每个区域的Cr,Cb分量的绝对偏差的均值Dr,Db:
      D r = ∑ ∣ C r ( i , j ) − M r ∣ N , D b = ∑ ∣ C b ( i , j ) − M b ∣ N D_r = \frac {\sum \vert C_r(i,j) - M_r\vert }{N},D_b = \frac {\sum \vert C_b(i,j) - M_b\vert }{N} Dr=NCr(i,j)Mr,Db=NCb(i,j)Mb

  • 最后整幅图像的均值 Mb,Mr 以及方差 Db,Dr 由除去T条件c后剩下的块计算平均值得到。

  • 选择候补白点,若某像素满足一下条件:
    C b ( i , j ) − ( M b + D b × s i g n ( M b ) ) < ∣ 1.5 × D b ∣ C b ( i , j ) − ( 1.5 × M r + D r × s i g n ( M r ) ) < ∣ 1.5 × D r ∣ C_b(i,j)-(M_b+D_b\times sign(M_b)) < \vert 1.5 \times D_b \vert \\ C_b(i,j)-(1.5 \times M_r+D_r\times sign(M_r)) < \vert 1.5 \times D_r \vert Cb(i,j)(Mb+Db×sign(Mb))<∣1.5×DbCb(i,j)(1.5×Mr+Dr×sign(Mr))<∣1.5×Dr

  • 然后根据候补白点的像素亮度值由高到低排列,从候补白点中选取亮度值在前 10%的白点做为参考白点。白平衡的增益值就是根据选取的参考白点确定的。

  • 为了让校正后的图像亮度跟校正前的图像亮度保持在同一水平,在增益计算时采用最大的亮度值作为参考。增益系数的计算公式公式如下:

R g a i n = Y m a x R a v g w , G g a i n = Y m a x G a v g w , B g a i n = Y m a x B a v g w R_{gain}= \frac {Y_{max}} {R_{avgw}},G_{gain}= \frac {Y_{max}} {G_{avgw}},B_{gain}= \frac {Y_{max}} {B_{avgw}} Rgain=RavgwYmax,Ggain=GavgwYmax,Bgain=BavgwYmax

 function results = SkinWhitening(app,Img)
            value = app.Slider_29.Value;
            im = Img;
            im1=rgb2ycbcr(im);%将图片的RGB值转换成YCbCr值%
            YY=im1(:,:,1);
            Cb=im1(:,:,2);
            Cr=im1(:,:,3);
            [x, y, z]=size(im);
            tst=zeros(x,y);
            Mb=mean(mean(Cb));
            Mr=mean(mean(Cr));
            %计算Cb、Cr的均方差%
            Tb = Cb-Mb;
            Tr = Cr-Mr;
            Db=sum(sum((Tb).*(Tb)))/(x*y);
            Dr=sum(sum((Tr).*(Tr)))/(x*y);
            %根据阀值的要求提取出near-white区域的像素点%
            cnt=1;    
            for i=1:x
                for j=1:y
                    b1=Cb(i,j)-(Mb+Db*sign(Mb));
                    b2=Cr(i,j)-(1.5*Mr+Dr*sign(Mr));
                    if (b1<abs(1.5*Db) && b2<abs(1.5*Dr))
                       Ciny(cnt)=YY(i,j);
                       tst(i,j)=YY(i,j);
                       cnt=cnt+1;
                    end
                end
            end
            cnt=cnt-1;
            iy=sort(Ciny,'descend');%将提取出的像素点从亮度值大的点到小的点依次排列%
            nn=round(cnt/10);
            Ciny2(1:nn)=iy(1:nn);%提取出near-white区域中10%的亮度值较大的像素点做参考白点%
            %提取出参考白点的RGB三信道的值% 
            mn=min(Ciny2);
            for i=1:x
                for j=1:y
                    if tst(i,j)<mn
                       tst(i,j)=0;
                    else
                       tst(i,j)=1;
                    end
                end
            end
            R=im(:,:,1);
            G=im(:,:,2);
            B=im(:,:,3);
            
            R=double(R).*tst;
            G=double(G).*tst;
            B=double(B).*tst;
            
            %计算参考白点的RGB的均值%
            Rav=mean(mean(R));
            Gav=mean(mean(G));
            Bav=mean(mean(B));
            
            Ymax=double(max(max(YY)))*0.15;%计算出图片的亮度的最大值%
             
            %计算出RGB三信道的增益% 
            Rgain=Ymax/Rav;
            Ggain=Ymax/Gav;
            Bgain=Ymax/Bav;
            
            %通过增益调整图片的RGB三信道%
            im(:, :, 1)=im(:, :, 1) * Rgain * (value / 5);
            im(:, :, 2)=im(:, :, 2) * Ggain * (value / 5);
            im(:, :, 3)=im(:, :, 3) * Bgain * (value / 5);
            
            results = im;

        end

结果

DO_0@~IU673KJ_LN2V15AVL.png

参考资料:

  • https://zhuanlan.zhihu.com/p/352968273

  • https://www.bilibili.com/video/BV1Tv411J7tx/?spm_id_from=333.337.search-card.all.click&vd_source=a3419c58df1e72218b5b7df6e48a59d1

  • https://blog.csdn.net/weixin_44045163/article/details/107839028

  • 2
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值