2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构

本科的毕业设计内容是基于稀疏表示的图像SR重构。
由于在学习稀疏模型、超分辨率图像重构理论、凸优化以及相关的优化算法发的时候,感觉各博客资料驳杂,对于小白而言难如登天,花费了不少的时间在选文以及甄别好的系统讲解博客上,所以今日对毕业设计学习过程中出现的问题以及好的博客进行简单的整理与记录,希望能够帮助到其他对SR领域有兴趣的同学们!
虽然当下的科研Paper多以深度模型为主,但是传统的方法也不能丢掉,时来运转,三十年河东三十年河西,打扎实相关理论基础我觉得才是硬道理。
以稀疏模型纪念我的大学四年!

1 毕业感言:

       三年高中远远不及大学四年,时间仿佛具有加速度,我就已经毕业了。

       都说“毕业快乐”、“前程无限”,身处其中,感受着这些羁绊渐渐化丝化弦,只能说快乐个鸡毛掸子啊。送走了周围的一个又一个同学,看着他们的脸庞,知道其中的很多面孔以后都不容易再见到了。时间就像河流,而我们就像其中的沙石,随着水流从最开始的不曾相知到相遇,再被裹挟着散布到各地各处,说是身不由己,又是满腔情愿呐。

       毕业的这两天暴雨重重,不论是领到学士服以后,还是毕业晚会、毕业典礼、毕业聚餐,天空仿佛就是一场演奏会,在离别的日子里,奏响的却不是欢乐的曲子,以雨水和风为我们唱出一首《送别》啊。

       临近“再见”,才发现不仅仅是那些熟络而亲近的朋友,即使是那些平时吐槽的,平时膈应的,时而翻腾欲大怒除之后快的朋友也是依依不舍啊。分别之后,愿大家各自安好,放之四海皆能发光闪耀!我也不能停下脚步,拼搏下去!


 

2 本文目的:

      由于我在做毕业设计的时候非常痛苦,网上的相关资源整合非常乱,根本没有一个系统的讲解啊。对于一个没有相关课题经验的小白而言是“讲什么不懂什么”、“用到什么谷歌什么“,所以在毕业设计3月到4月底完成,5月份进行了简单的完善以后,有一定的文献阅读的今日,于此博客进行毕业设计科研过程的一个简单总结;

      对中间出现的问题进行记录以及原因分析;

      对课题的研究学习过程中的文献进行特点的简要总结;

      对课题学习过程中对各种新概念及名词学习时,找到的好博客进行记录;

      之后因时间以及个人问题,没能实现论文发表而表示遗憾。

      希望本篇博客能够对日后稀疏表示的图像重构技术的同学们有很大帮助!(深度学习这里没整理噢~)

       P.S. 由于本博客的意义是记录以及个人感受,所以尽量采用通俗的方法进行扯淡。

      以此纪念我过去的大学四年。


 

3 课题概述

       这里简要的讲解一下课题的名称、意义、内容、和路线,在下一章进行课题中使用的各个方法的具体理解。

3.1 课题名称:基于稀疏表示的超分辨率人脸图像重构

3.2 课题的意义:

      我的理解是——狭义的来讲,由于高分辨率很重要,但是获取更高的分辨率图像会有很多限制;广义的来讲,很多时候图像不清晰很模糊,希望能够图像质量更好——用“超分辨率重构技术“(Super-Resolution, SR),放心呵护放心爱,夜光照亮你的美,使劲拍照,我们来帮你更清晰~

       因为低分辨率的图像由于像素数有限,肯定是没办法表达出非常多的细节信息的,所以如果能获取高分辨的图像,那我们肯定是喜闻乐见,图片就可以放大放大放大!而超分辨图像重构就是能将一张原来是低分辨率的图像,用算法提升它的分辨率,这不是从软件的角度上解决了硬件的问题吗,流批!(这个是广义的理解,把低分辨率变高分辨率)

      比如之前的华为手机拍月亮,拍的月亮虽然不一定清楚,但是内置的超分辨算法可以实现对拍出来的模糊的月亮进行细节提升,把糊糊的照片变得清晰可见!(这个是狭义的说法,将糊糊的图像变清晰)

       (应用领域有很多,这个就不赘述啦~)

 

3.3 课题内容:

      输入一张低分辨率(Low-Resolution, LR)的图像,经过模型算法吭哧吭哧输出一张高分辨率(High-Resolution, HR)的图像,这张分辨率要更高,放大图片的不会非常模糊啊或者是细节很不对劲啊什么的。

      课题的核心问题:按照上面的这个思路,超分辨率重构的思想就是,将一张信息不够多的图像变成一张富含更多信息的图像~那容易出现一个问题就是,如果你没搞好这个“无中生有“的过程和思路,就会从”提升性能“走向”瞎扯造假“了。如果你”无中生有“出来的图像信息是符合现实依据,是有的,那你就是好算法,提升了性能;如果你“无中生有”出来的图像信息是现实中没有的东西,结果你的算法把它给重构出来了,那不是扯淡吗(╯°Д°)╯︵ ┻━┻

      前沿技术:现在都是深度学习的时代了,高重构效果的方法技术大多是深度学习。。。像基于稀疏表示方法的重构是非常传统的了,CVPR近年的超分辨率重构文章都是基于深度的,PSNR值都能达到40+了,这还是人吗。。。主要是基于各种网络:残余网络啦、对抗网络啦等等。本文只讲传统的稀疏表示模型的重构路线。

 

3.4 课题技术路线:

      样例算法思路如下~

      预处理:将输入的低分辨率LR图像,以及数据库的高分辨率与低分辨率图像对,都进行相同的分块操作;

      字典学习:然后对数据库图像对进行一个字典学习过程,得到字典D;

      稀疏优化:对于输入LR图像的各个图像块,基于刚刚求得到的字典D中的DL部分进行稀疏模型的优化求解,得到稀疏系数矩阵;

      重构过程:利用求得到的稀疏系数矩阵以及字典D中的DH部分就可以重构出对应的各个图像块了;然后把这些块拼起来就得到输出图像。


 

4 课题详谈:

4.1 数据库的获取:

       人脸数据库我是按照人脸检测数据库取的,一些国外的数据库还需要发邮件进行申请,这谁顶得住,贴下这个连接,同志们可以使用一下,我使用的ORL数据库啦。

       各大人脸图像数据库获取链接:https://www.jiqizhixin.com/articles/2018-10-23-4

       FDDB人脸图像数据库获取链接:http://vis-www.cs.umass.edu/fddb/

 

4.2 分块重构:

      90%基于稀疏模型的超分辨重构路线都是非常一致的,采用图片分块重构。什么意思呢?如果我要将一张输入的低分辨率图像X给超分辨率重构成一张高分辨率图像Y,总不能一下子直接就复原搞出来了吧。。。最传统的做法是,把一张图像分成好多块,就和切披萨一样,每一块披萨,哦不,每一块图像块各自想办法重构出来。比如说,我有一个人脸,这个人脸图片糊不拉几,但是这么大的图片也不能直接重构,所以我们把人脸分割成眼睛啊鼻子啊各个块,然后每个位置想办法进行重构出来,再拼起来,不就可以完成人脸图像的重构了吗?

 

4.3 稀疏模型:

      那对于一个块而言,怎么去重构对应的块呢?用稀疏模型可以解决这个问题。

      什么是稀疏模型呢?可以参考这个博客:https://www.cnblogs.com/hdu-zsk/p/5954658.html

      大概这么说吧。所谓的傅里叶变换抑或是泰勒公式,都在告诉我们一个道理,很多数学函数或者表达式都是可以由很多乃至无限的基本“元素“垒起来的!这个物质世界也是如此,小到原子、 分子,大到砖头、别墅、地球,也是由更小更多但是却有限的基本”元素“垒起来的!而稀疏模型,作为信号领域的理论,它的本来意思是,一个信号X,也是可以由某一组有限的基信号(原子)D叠加获得!怎么叠加呢?每个信号有自己的系数,这个系数就和多项式的系数一样,把这些原子各自按照这个系数的倍数,加在一起就可以获得信号X啦!

      是不是很神奇?不管是什么学科,反应的哲学思想还都很相像~

      那我们把这个稀疏模型拿到线性代数里面也是适用的,而且我觉得更好理解了!——一个向量X,必然能够由某一组有限个数的基向量D表示出来。(这个要是不能理解,那肯定是你的高中正交分解没学好,嘿嘿嘿)

      敲黑板,上面稀疏模型的重点是“有限个“,泰勒公式才是”无限个“。

      对吧!那图像是什么啊?图像就是像素集呗!像素集怎么表示?就是用0到1的浮点数集合或者是0到255的整数集合来表示呗!那如果我把一个图像变成压成一列,这个灰度表示的图像整数列表,不就是一个向量吗!

      图像就是向量!所以说,任何一个图像X,也肯定是可以由某一组有限的基信号(原子)D叠加获得!说的学术一点,图像也是可以进行稀疏表示的。

      假设我已经求得到了这个基组D(后面我们把这个基里面的各个向量叫原子,整个基叫做字典),如何求向量X在这个D上的表示系数呢?这就是稀疏优化模型要解决的问题,怎么去求稀疏表示系数矩阵。方法有很多种,后面再讲。总结一下,这个“可线性叠加“,就是稀疏表示;这个模型思想,是稀疏模型;这个系数求解方法,叫稀疏优化算法

 

4.4 字典学习:

       上面的稀疏模型的核心思想是:如果我有一个向量X,那肯定是可以在某个字典D上进行线性表示的,可以用稀疏优化算法去求;那问题来了——你怎么知道这个D是啥呢?你没说这个D咋求啊!如果我单单的给你一个向量,然后说好了你可以开始稀疏表示了,你肯定是一脸“???“,因为没给你D啊。所以这个D我们肯定是要想办法获取滴,获取这个D的过程就是”字典学习“过程。有很多解决这个问题的算法,例如KSVD算法,大概是利用奇异值分解实现 balabalabala 的稀疏系数与字典D的交替迭代求解,得到一个局部最优值,虽然方法比较老了,但是还凑活吧~

      我们用线性代数的向量来表示的话,就是一个N维的向量如果要想办法用一组基来表示,那肯定至少需要N个原子构成基对吧,也就是要满秩才行呢!

      比如说,我有一个二维向量,我们平时建立的表示二维向量的直角坐标系是两个基向量吧——横坐标方向的单位向量i和一个表示纵坐标的单位向量j,你不可能给我一个原子作为基,就去表示一个二维向量吧?

      再比如三维的向量,我们平时的表示方法,也是建立一个直角坐标系,这个直角坐标系也是由三个基向量的呀,i、j、k,但是一定是三个原子就一定能表示一个三维向量吗?那当然又不对了!肯定是要三个不共线的原子啊!比如说我有100个三维空间的原子,一个是i,第二个是2*i,第三个是3*i,…,一直到第100个是100*i,那这个100个原子中的99个原子都是混子啊!都是来滥竽充数的废物啊!搞了半天就是1个有效的基呗,其他的就是放大了呗,那有个球有个锤子用哦!所以我们说,要有几个原子随便你,一定要有秩为3的原子库就OJBK了。这个秩就是有效的、不共线的、同时不能被其他原子表示的原子的个数。

      如果我还帮你了搞明白了线性代数的秩的理解,请给我点赞,哈哈哈哈哈。

      哦对了,我讲了上面这个基的要求有什么意义来着——就是说我们一般情况下要获得的字典,肯定是冗余字典。首先我们所有的原子都是按照列向量来表示的,每个列向量如果是N维(行数),这个字典中原子的个数是M个(列数),我们肯定是要求这个M大于N的。道理呢就是我上面讲的。要是N都达不到,还表示个P啊,这个字典已经可以宣布效果一般了。

 

4.5 联合字典学习:

       那看完上面的人可能有一个疑惑?那如果要填满整个向量空间的基,来能够表示出某个向量X的话,那为什么不直接选用直角坐标系的向量基作为字典D呢,比如三维空间就直接选i、j、k不就好了?肯定能表示出向量X啊!

       嘿嘿,如果你这么想,那你就被我带偏了。

       我们这个课题是怎么求这个向量表示吗?NO!

       我们要解决的问题是重构图片!重构图片啊!

      我们求稀疏表示模型的时候,用到的字典和重构图像的时候用到的字典某种角度来说,其实不是同一个字典呐!

      举个例子,我要复原出输入的低分辨率图像LR一个人脸的鼻子,这个鼻子很糊,怎么样才能重构出一个精致又逼真,和现实中这个人鼻子一样的前提下,更清晰的鼻子呢?让这个鼻子拥有更清晰的鼻孔和鼻毛,还有鼻子上的黑头和汗水、油位呢?

      那我要首先采集其他N个人的鼻子照片,假设是100个人好了。这个鼻子图像建立的数据库肯定是高清的大鼻子咯(HR),然后我将这个HR鼻子人工变成和我输入的LR图像一个清晰度级别的LR字典DL。然后我们在这个DL中选择距离待复原的人的鼻子最像的几个鼻子,求出稀疏表示系数之后,我们要用对应的这几个DL的鼻子,的高清的图像字典DH的来复原。——即,用低分辨率LR字典DL进行系数求解,用高分辨率DH字典进行稀疏重构。如此一来,就不会产生,为什么不用坐标系的基进行稀疏表示的疑问了吧~因为它们没有对应的HR向量了呀!

      而为了保证这个字典的LR与HR原子对的关系,我们在训练字典的时候就把HR原子和LR原子捆绑在一起,一起学习,美其名曰:联合字典学习咯~

       上述讲的这个字典一定是要冗余,冗余的话呢这个字典的重构效果就会更好!啊?为什么用这个字典进行重构效果就会好?拿到重构领域来说,因为我们是将图像分块,每个块进行重构,所以就是每个图像块就是原子向量。这个字典冗余、大,就代表这个块多,就会包罗万象。还是拿上面这个例子,我要复原出低分辨率图像LR一个人脸的鼻子,那我采集了其他5个人的鼻子,选择距离待复原的人的鼻子最像的几个鼻子来复原;和我采集了1W个其他人的鼻子,选择距离待复原的人的鼻子最像的几个鼻子来复原,哪个效果好嘞?不言而喻了吧~但是我不能说,我直接用直角坐标系的基来进行复原吧~这样一来,我们用这个字典进行重构的效果就会好!

 

4.6 特征提取:

       那还有一个问题。我们就算是要复原一个人的鼻子,那这个鼻子的图像上肯定有很多干扰对不对~比如说,我要重构一个人的鼻子,我肯定是要使得它的鼻子更清晰,鼻毛看的更清楚,鼻孔更加深邃,黑头更加有规则,结果到时候重构出来,把图像中原来的颜色灰度更加细腻了有个球用。也就是说,要对图像上的关键信息进行提取,能够获得更好的重构效果啊。

       不同的Paper使用了不同的特侦提取策略,这个我们后面再聊,于此是为了讲解此步骤的意义所在。

       简单的看过此博客,讲解不同的特征算子:https://blog.csdn.net/chengjunda22/article/details/68943632


 

5 核心算法学习

5.1 稀疏表示优化算法

5.1.1 OMP算法原理(效果中上,快)

       所有的博客在讲解OMP算法的原理都是从MP算法进行引入的。但实际上确实是这样。

       MP算法(匹配追踪)思想就是,在一个字典D上如何去“分解“待求向量X。而这个分解的思想其实和高中物理中受力分析的”正交分解“差不多的,只不过高中物理的”正交分解“是分解成两个正交向量,而此处的字典D并不是正交的向量集,所以采用的分解思路是采用”向量投影“实现分解。

       顺着这个思路,去理解OMP算法就会方便很多吧(我是这样)。这里有个博客是采用绘图的形式,能够更好的理解这个过程:https://blog.csdn.net/pi9nc/article/details/18655239

       还有三篇更加细致、学术的论述博客,写的都很好:

       https://blog.csdn.net/scucj/article/details/7467955

       https://blog.csdn.net/wwf_lightning/article/details/70142985

       从给一个具体的例子进行解释的博客有:https://www.cnblogs.com/theonegis/p/7653425.html

       还提供了源码的博客(但我没有用过):https://www.cnblogs.com/yangnk/p/6725329.html

       以上几篇博客是我在学习过程中,觉得最好的也是最容易理解的博客啦。讲道理,OMP思想就和普通其他的贪心算法一样比较简单,但是也能有这么多学问,真的很了不起!在学习OMP过程中可以借鉴我的轨迹进行学习~

5.1.2 OMP算法源码

       虽然上述博客给出了源码,但是同一个算法,不同的人写出来的效果差的实在是很多,我没有对各大不同同志们写的OMP进行一个性能分析,一是因为懒,二没有那么多时间,三是我并没有那么强的理解能力。一个算法好的撰写需要对程序语言以及算法本身具有很好的理解,才能写出好看工整甚至是快速高效的代码。

       我是用的平台是Matlab2018b,思量之后,采用的是PUDN上的OMP代码,作为稀疏表示的初学者其实够用,但是效率一般啊,着实比不上Paper里的效果,在后续项目优化的过程中进行了更换。

 

function [X]=OMP(D,Y,L); %返回稀疏系数,大小是50*1500
%=============================================
% Sparse coding of a group of signals based on a given 
% dictionary and specified number of atoms to use. 
% input arguments: 
%       D - the dictionary (its columns MUST be normalized).归一化的字典
%       Y - the signals to represent     待表达的信号
%       L - the max. number of coefficients for each signal.  每个信号的系数的最大个数
% output arguments: 
%       X - sparse coefficient matrix.稀疏系数矩阵
%=============================================
[n,P]=size(Y);%信号大小20*1500
[n,K]=size(D);%字典大小20*50
for k=1:1:P,%1到1500次循环,间隔是1
    a=[];
    x=Y(:,k);%信号的第k列(即第k个信号)赋给向量x,向量x是第k个信号向量
    residual=x;
    indx=zeros(L,1);%索引是三维列向量
    for j=1:1:L,    %1到3次循环,间隔是1
        proj=D'*residual;%得到50*1,第k个信号的系数向量,D的转置就是D的逆,因为D是正交的
        [maxVal,pos]=max(abs(proj));%找到这个系数当中绝对值最大的数值及位置下标
        pos=pos(1);
        indx(j)=pos; %把最大数值的下标赋给索引的第j个分量
        a=pinv(D(:,indx(1:j)))*x; %D的部分列的伪逆矩阵再乘以x,意思只取算出来的系数中最大的j个分量对应的字典原子的违逆乘以信号得到一个系数
        residual=x-D(:,indx(1:j))*a;%用信号减去上面的系数乘以对应字典的列得到初始信号与稀疏表示的信号的误差
        if sum(residual.^2) < 1e-6  %判断误差是否在限制范围内
            break;%在,结束for循环
        end     %否则继续循环
    end;
    temp=zeros(K,1);%K=50维向量
    temp(indx(1:j))=a;%a是有最大的j列个元素的系数,最后所求的最多有三个分量的第k个稀疏系数50*1,
    X(:,k)=sparse(temp);%生成稀疏矩阵的k列
end;
return;

      

5.1.3 OMP算法存在的问题(我还没去解决)

       第一,MP的稀疏优化算法在所有方法中可以算是最快的了,但是稀疏效果一般。OMP的稀疏度需要自己确定,一般采用0.15到0.20左右,稀疏性有一定保证,但整个稀疏表示一般吧,在整个算法框架中会成为一个制掣,导致效果上不去。经过我的推测,不采用OMP算法后,整个项目效果上升了一个档次。

       其次,有很多Paper的稀疏优化算法采用OMP或者是OMP的优化版本(Batch-OMP等),并且程序能够得到很好的效果。但我不行,经过一个月的调试,我确定OMP的稀疏求解误差还是比较大的,并不能成为一个高效理想的稀疏模型求解工具。但是这个问题到底是为什么呢?都是OMP算法,这种基于贪心的算法在撰写上应该不会存在特别大的差异才对,至今我没有对众人的OMP算法进行对比。但是看着很多硕士、博士、Paper的基于OMP的超分辨率重构效果上升,我是不能理解凭什么?也许是他们各自的OMP算法都有一些小优化吧,有些开源有些没开源以至于我也无法论证;也有可能是他们的程序中有加入一些没有在论文中多说或提及的小Trick,不得而知,没有进行相关调研,待日后有机会我再更。

5.1.4 ADMM算法原理(效果良好,慢)

       ADMM算法(交替方向乘子法)是真的让我又爱又恨。这是我的项目最开始尝试使用的方法,但是GG了。

       恨是因为ADMM算法我学习了1个礼拜都没有太大收获,网上么原理一大堆,源码屁都没,不懂原理也不知道好不容易找到的源码真的假的,跑出的结果也是一坨屎,而源码里面的参数都看不懂,注释寥寥几句都是浮云毫无意义,mmp看得我真的沮丧不已,最后花了20天到3月底程序框架全部写完了ADMM算法也没有啃掉,一怒之下选择了OMP算法,走向幸福快乐的初步小康生活。

       爱是因为后期OMP效果有瓶颈了,我又一次回到ADMM的怀抱,这一次从源码调用的角度,将ADMM成功使用,同时在学长帮助下获得了更优质的ADMM算法源码内容,使得项目进入全面小康。。。(笑死)

       有很多博客写ADMM算法的原理,对于我这样的咸鱼真的是看着脑壳疼啊。很多名词都是在学习ADMM算法过程去顺便学习的。ADMM算法原理真是又臭又长,不就是一个迭代更新吗,怎么能写的这么复杂啊。。。

       实不相瞒,ADMM算法我现在也只是懵懵懂懂,完全理解还需要下次去学习。

       我在这里列一下我在学习ADMM中个人整合的,觉得不错的博客资源吧~

      

       首先,如果你要理解ADMM的“乘子法“思路,你需要理解什么是”对偶上升法“;如果你要去理解好什么是”对偶上升法“,你需要去理解什么是”梯度上升法“。(是不是又臭又长)

       好的,什么是”梯度上升法“呢?来来来,看这个博客:https://blog.csdn.net/c406495762/article/details/77723333

       啊,有一点点理解了,那什么是”对偶上升法“呢?

等一下!要想理解”对偶上升法“呢?那我们需要知道什么是”对偶问题“,于是我看了这个博客:https://www.cnblogs.com/ooon/p/5723725.html

知道了什么是”对偶问题“,我们继续学习什么是”对偶上升法“,来来来,看这个博客:https://blog.csdn.net/shenxiaolu1984/article/details/78175382  

       噢,我好像懂了一点了。那什么是ADMM算法呢?

       给你一个超级细腻超级细腻的讲解博客,简直是讲解了ADMM的各种方法以及各种原理呀:http://spiritsaway.info/admm.html#022eb3

       什么,这个博客太复杂了?那你可以看看这个比较随便的;https://blog.csdn.net/qauchangqingwei/article/details/82112103 ;其实这个博客是转载自知乎的回答,原帖在这里; https://www.zhihu.com/question/36566112

       如果你看完上述内容就懂了,那你就是大佬。

       我还参考了一下俩博客才有所理解来着:

       额外简洁版本:https://www.cnblogs.com/breezedeus/p/3496819.html

       额外复杂版本:https://blog.csdn.net/angel_yj/article/details/40587543

 

       我再说一遍,ADMM算法原理看得我真的是又臭又长。但是收获也不小啦,看完ADMM我感觉我爱上了高数,就连一个拉格朗日乘子都这么神奇~,什么,你问我什么是拉格朗日乘子,你也忘记了?来来来,我也是忘记了重新查的(狗头),看这个博客:https://blog.csdn.net/ccnt_2012/article/details/81326626

       ADMM原理的学习过程大概就是这样,这些博客可以帮助你很好的去学习ADMM。但是问题来了:源码在哪里呢?

5.1.5 ADMM算法源码

       这个源码emmm ,老实说效果一般吧,不是我后来使用的改进的ADMM算法啦。是我第一次使用的ADMM版本,诸位可以借鉴一下。后来版本的ADMM引用到不同文件和库,这里单独发是发不下滴。

       随便用用的话,可以参考下面这些网址啦~

       首先是ADMM算法的源码:https://web.stanford.edu/~boyd/papers/admm/lasso/lasso.html#5

       当然是MATLAB版本的啦,如果你看懂输入参数,那就没有问题~

       这是斯坦福学院提供的工具包,就这我都找了好几天。。。看来是信息检索能力不行啊。

       它还提供了使用的样例教程:https://web.stanford.edu/~boyd/papers/admm/lasso/lasso_example.html

       大家可以使用试试看(坏笑)

       就是太慢了。

5.1.6 其他方法(效果优,快)

       后来我使用的就是其他方法啦。

       什么意思呢?

       就是去查看各经典文献Paper的源码,有些开源有些没有开源,然后将其中的代码剖析出来,得到我需要的稀疏优化算法的部分。比如后面我会提到的Yang的【Image super-resolution via parse representation】经典之作,是开源的,欢迎前去膜拜,对我受益匪浅!

     扒代码考验你对整个框架的理解,以及对作者论文拜读的熟悉程度,以及个人的编码能力。看完代码你会发现有很多新的收获。

       大牛写的的代码,敢开源都不会差的。很多时候,看完他们的代码,我会感叹事情可以被这么简单的解决;或者是感叹原来这个思想是这样的啊

       论文只能反映建模思路,代码能反映更深刻的问题解决过程

5.2 字典学习KSVD算法

5.2.1 KSVD算法原理(慢的一匹)

       写到这里写的都有点累了。

       KSVD算法是用来解决什么问题的呢?就是给你一大堆图像块,如何训练出一个优秀的字典D!

       简单的讲一下KSVD算法我的理解,就是先固定住字典D,然后去求稀疏优化系数(比如用前面提到的OMP);得到这个系数以后,欸,我固定这个系数,修改这个D使得这个D能够更好的适应这个系数;不断的切换切换,使得最后的D能够稳定下来。

       当然啦,这样讲是没有KSVD算法灵魂的。

       学习KSVD算法,首先最好去学习K-Mean聚类算法的实现逻辑。当当当当,可以看这个博客(这个博客我其实忘记了,这是重新找的,这个聚类过程的图还不错):https://www.cnblogs.com/jerrylead/archive/2011/04/06/2006910.html

       所以说,KSVD算法中的K是要训练出K个原子,而SVD是因为这个算法核心需要用到“奇异值分解“(SVD)的思想。学习KSVD过程中我没有特别印象深刻的博客,就记得这个了。。。:https://www.cnblogs.com/endlesscoding/p/10090866.html

5.2.2 KSVD算法源码

       KSVD算法源码我还是在用,但是揪心的地方是:太慢了!

       迭代次数设置为20,训练集为6000个块,学习1024个字典,我记得都要12个小时。。。

       KSVD引以为傲的速度是快,但也不过如此。。。真是让人沮丧啊

       参考网址:http://www.pudn.com/Download/item/id/1438085.html

       同样的道理,可以使用扒别人源码的方式获得更优质的轮子,或者舍弃字典学习的过程。在此不赘述。


 

6 建模过程

       啧。写不动了。反正都是一些Paper里写烂的公式,我也懒得再截图了,此处日后再补吧~

       要注意的地方就是,拉格朗日乘子、规格化、L1/2正则化理解与掌握,为什么要采用这些东西改变式子,要好好理解,我先懒得写了。


 

7途中出现的BUG与思考历程记录

7.1 本人工作内容

       完成了对整个项目的完全独立实现。但是后来由于效果的局限,采用了Yang的L1稀疏优化算法(一个.m文件)和网上的KSVD算法(也是一个.m文件),其他部分无搬运工作,实现实验的复现优化,基于Yang的Paper的论文,加了局部约束、全局约束,并加入个人的迭代约束,实现PSNR值的性能提升,比双三次插值PSNR值高3左右。

7.2 出现的BUG

       笑死。在项目初期(3月份)的时候,出现了太多的问题。在这里贴几个,笑掉大牙了,左边是期望输出的原始HR图像,中间是输入LR图像,右侧是实际输出。

  • 主要是由于数据集太小,字典不够冗余;以及OMP算法掌握不熟练,未加入约束 ,以及向量的规格化操作未考虑周当,出现的重构效果(木乃伊了 哈哈哈哈):

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第1张图片

  • 加入邻域约束,结合是否规格化数据得到的不同结果:

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第2张图片

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第3张图片

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第4张图片

  • 使用版本一的ADMM算法,但是没有规格化好,把系数倍数搞烂了,变成了下面这样:

 

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第5张图片

       总结为什么会出现上述的这些情况呢?

       首先,我当时重构的思路是各块重构时采取不同图像的对应位置快作为字典D进行重构。但是一共才使用了40张人脸图像作为字典,而且还是不同人脸,这40张图像采取到的40个原子个数实在是小的可怜,而且差异化巨大,难以重构出原始人脸。后来我退而求其次,使用整体统一的字典D,由6W个数据块训练出1024个字典,性能直接上来了。

       其次,我的编码有一定问题,参数设置有一定问题,OMP本身具有很多局限难以精确,而最重要的是整个稀疏模型中的“规格化”步骤没有搞清楚。

       论文只能反映出你是如何实现如何思考大方向的,但是课题研究和项目需要拿出优秀的表现,在很多的小细节上会产生决定性的作用,但是这些论文里面往往都不会进去。

       每一次思考错误原因和DEBUG都让我欲仙欲死,这和思考代码问题不同,我要去思考我的整个模型方案错在了哪里等等,非常有趣!

7.3 部分思考历程

这部分纯当记录哈哈哈哈,说实话,这做毕设的感觉才是我想象的科研感觉呀(虽然很初级)。之前做了3次不同的科研工作,独属本次科研令我大有裨益而意犹未尽。

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第6张图片

7.4 程序实现小Trick

       要想程序的效果获得更好的提升,不说什么重构方案上的优化,只谈一些小细节能够显著的提升PSNR值的,我结合我的经验给出以下建议:

  • 加入全局约束(后处理),可看Yang文献内容。
  • 基于残值重构。(我还没应用残值重构呢,就已经效果显著了)
  • 恰当的特征提取方式比字典从1024到10240或者是是否特意加入字典学习过程更重要!
  • 全局约束>局部约束。全局约束可以提升客观的PSNR;局部约束实现主观效果邻域块间更平滑,但是会降PSNR。
  • 迭代效果会提升0.23到提升0.02程度衰减,辅助手段而已。
  • 稀疏优化算法很重要,效果上:Yang的>学长的L1>我的ADMM>OMP

 

8 最终实现效果

       下采样因子取的是2,块大小采取5×5.

  • Lena图像——比较大看不出来

 

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第7张图片

 

  • 基本人脸图像

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第8张图片

 

2019毕业设计总结——基于稀疏表示的人脸图像超分辨率重构_第9张图片


 

9 未来工作计划

       有几个想法,但由于时间以及因素,无法将方案实时并发表我的学术论文(如果有机会,毕竟俺是无硕士可读的废物来着,噗哈哈哈)


 

10 部分参考文献

       毕设结题前的基本稀疏表示模型的部分参考文献(可以用来打基础)

       [1]李文文. 基于稀疏表示的单幅图像超分辨率重建算法研究[D]. 兰州理工大学, 2017.

       [2] 浦剑, 张军平, 黄华.超分辨率算法研究综述[[J].山东大学学报(工学版), 2009, 39(1): 27 一 32.

       [3] 练秋生, 张伟.基于图像块分类稀疏表示的超分辨率重建算法[[J].电子学报, 2012, 40(5): 920-925.8

       [4]李欣. 基于稀疏表示的图像超分辨率重建研究[D]. [出版地不详]: 南京邮电大学, 2016.

       [5] 李珅. 基于稀疏表示的图像去噪和超分辨率重建研究[D]. [出版地不详]: 中国科学院研究生院(西安光学精密机械研究所) , 2014

 

       核心论文:

       【2010稀疏代表性】【核心Paper】Yang的Image  super-resolution  via  sparse representation——核心经典

       【2011遥感景物】Single Remote Sensing Image Super-Resolution and Denoising via Sparse Representation——用KSVD和Batch-OMP,其他同Yang,应用于遥感景物。

       【2012字典分类】Sparse representation and position prior based face hallucination upon classified over-complete dictionaries——实际上就是对应patch进行重构罢了,美其名曰分类。无字典学习无特征提取无约束,是OMP

       【2014翻译】Face super-resolution via multilayer locality-constrained iterative neighbor embedding and intermediatedictionary learning——多层迭代重构

       【2017学长基本】Noise Robust Face Image Super-resolution Through Smooth Sparse Representation. Junjun Jinag——增加一个稀疏系数的平滑约束

 

       其他的懒得补充了。基于深度模型的我就不添加了,还有后续规划的参考资料待论文能发表时再更吧~

你可能感兴趣的:(科研之路)