RAISR(Rapid and Accurate Super Image Resolution)

来源:互联网 发布:mt4 一键下单脚本源码 编辑:程序博客网 时间:2024/06/06 17:45

RAISR(Rapid and Accurate Super Image Resolution)

Rapid and Accurate Super Image Resolution为快速精确的超级图像分辨率技术,用于图像的压缩,意在将低分辨率图像转换为高分辨率图像.

github代码为:https://github.com/MKFMIKU/RAISR

对于给定的图像,我们希望可以得到一个尺寸更大,且含有更多有意义的像素点和更高质量的图像.这就是单幅图像超分辨率Single Image Super Resolution (SISR)技术要解决的问题.原理是,给定足够多的训练数据,训练数据为低,高分辨率图像对,我们可以学习一系列滤波器,使用这些滤波其可以处理训练数据以外的图像,而得到更高分辨率的图像.

一个相关的话题是图像锐化和对比度增强,例如增强模型图像的细节信息.我们的方法附加的增加了一个极度有效的方法,处理厚的图像比输入图像边沿更清晰.而没有引入光晕效应,噪声等瑕疵.

Single Image Super Resolution (SISR)

SISR公式为:

z=DsHx

式中,zRMxN,xRMsxNs,HRMNs2xMNs2 为模糊核,用于对模糊输入图像x,在每个坐标轴上,有一个因子s用于控制模糊核.

该目标函数的目的是,学习模糊核H,和Ds以使得,对数如低分辨率图像,通过改式得到输出高分辨率图像.

RAISR:

给定一个高分辨率图像yiRMxN ,i=1,...,L,我们的目的是学习一个dxd 的滤波器h,使得输出y和理想的高分辨率图像xi尽量相等,这个可以通过求解下列最小平方函数得到:

minhLi=1||Aihbi||22 (1)

式中,hRd2为滤波器,AiRMNxd2为矩阵,由图像yi中的dxd大小的块组成,每个块组成矩阵的一行.向量biRMNyi的块的中心的对应于目标图像xi的像素点组成.

训练和测试过程图如下:

这里写图片描述

由于矩阵A很大,因此我们采用两种单独的算法控制估计滤波器,降低计算复杂度.首先,在大体上,不是所有的可以的得到的块都需要被用于得到一个可靠的估计.事实上,可以从图像中采样k个块/像素点,这里

K<<MN
.其次,最小平方问题的最小化,如上公式(1),可以通过扩展到多幅图像,多个滤波其的思想.代替最小化等式(1),我们可以最小化下式:

minh||QhV||22

式中,Q=ATA,V=ATb,Q为一个d2xd2的小矩阵,这样就相对减小了内存.同样的,相对于向量b,向量V也同样的需要更少的内存.此外,基于矩阵-矩阵,矩阵-向量相乘的概率,我们事实上消除了在内存中存储整个矩阵.更具体的说就是,Q可以通过通过行累加计算,从而可以单独相乘,公式如下:

Q=ATA=jATjAj

即可以对矩阵A的每行单独计算,所有行的计算结果累加得到Q.

同理可以计算V:

V=ATb=jATjbj

这样计算复杂度和内存消耗都大大减小了.

改进cheap upscaling kernel

改进后的结构图像如下:
这里写图片描述

如上图所示,在每个坐标轴上,以因子s=2,上采样,双线性核的插值权重岁像素点的位置改变.可以看到,有四个可能的核,更具像素点的类型,他们可以被用于低分辨率图像,标记为P1-P4.由于两个线性滤波的卷积可以统一为一个滤波(在我们方案中,第一个滤波器是线性的,第二个是预先学习到的),因此,可以学习四个不同的滤波器,它们对应于相素的四种可能的类型,如下图所示:

这里写图片描述

图中为滤波器和其对应的频谱图.学习到的滤波其类似于带通滤波器,可以放大插值图像的中间频率,并压缩高频部分.

在实现阶段,类似与core/naive upscaling思想,首先是采用双线下插值上采样低分辨率图像.之后,与naive approach不同的是,根据像素的类型,使用预先学习得到的滤波器对其进行滤波处理,之后结合每个滤波块得到输出,过程图如下:

这里写图片描述

RAISR: HASHING-BASED LEARNING AND UPSCALING

大体上说,全局图像滤波是快速的,由于学习策略减小了高分辨率图像和低分辨率图像的插值图像的欧式距离,全局滤波可以改善各种线性上采样的重建效果.然而,全局滤波的方法仍比核心算法,如基于稀疏的方法(文献1-11),或者基于神经网络的方法(文献16)效果差.我们建议使用一个高效的哈稀方法(hashing approach)来自适应滤波以保持线性滤波的低复杂度.更简单的说,局部自适应可以通过将图像块依据梯度信息分组分组实现.

与全局方法类是,我们学习四个滤波器,但这次是对每个bucket.这样,所提的学习策略可以得到滤波器的哈稀表,哈稀表的keys为局部梯度的函数,哈稀表的entries为对应的预学习的滤波器,具体过程图如下:

这里写图片描述
与全局学习过程类似,我们利用矩阵-矩阵,矩阵-向量相乘,对于每个bucket q,我们学习一个滤波器hq,使得式最小:

minhq||ATqAqhqATqbq||

式中,A_q,b_q为第q个bucket的块和像素.

求解哈稀表的keys值

哈稀表的keys为局部梯度统计值,包括angle,strength,coherence.对于每个像素点,可以利用其周围的n×n 个像素点,例如对第k个像素点,由其周围的像素点的水平和垂直梯度,gx,gy 组成,

这里写图片描述

如文献35所述,局部梯度统计值可以通过矩阵Gk的SVD计算.我们可以更高效的计算这些特征值,通过使用GTkGk的特征分解(eigen-decomposition)求得,矩阵大小为2×2.另外,为了引入每个像素点的梯度值的领域,我们应用一个对角权重矩阵Wk ,其由一个可分离的归一化高斯核组成.

与文献35一样,特征向量ϕk1对应于GTkWkGk的最大特征值,并可以用于求解梯度角度θk,公式为:

θk=arctan(ϕk1,y,ϕk1,x)

由于对称性,对应于角度θk的滤波器与对应于角度θk+180o的滤波器是同一个.

如文献35所示,最大特征值λk1的平方根类似与梯度的strength.更小的特征值λk2的平方根可以被认为是局部梯度的spread,或者他们在方向上变化多少.这两个特征值被结合为一个衡量值,coherence ,用符号μk表示,取值范围为0到1,计算公式如下:

μk=λk1λk2λk1+λk2

强度(strength)和相关性(coherence)是对于检测局部图像值的不同性是很有用的.低的强度和相关性通常代表该图像缺乏结构性,并且通常对应于噪声或者压缩瑕疵.高的强度,但低的相关性通常表示角落或者其他多方向结构.因此,结合角度θk,strength λk1,以及coherence μk带哈稀函数,如算法1表述,可以学习到一系列滤波器,他们可以处理各种情景的图像.

算法1表述如下:

这里写图片描述

使用块对称来学习领域的8×更多的数据

学习高效,稳定的滤波器需要大量的数据,例如实际上,需要105个块来稳定地学习一个大小为9×9或者11×11的滤波器.例如,我们把块分为B个buckets,当使用一系列哈稀滤波时,对于每个bucket我们需要105个块.然而要达到这个数量,对于真实世界的训练数据并不像使用105×B个块那么简单.

问题是,对于图像中的平坦区域,通常含有更多的水平和垂直结构,这些普遍的结构导致了普遍的哈稀值.为了使得非普遍的哈稀值的块更高效,我们利用块的对称性,并增加每个块的学习程度.具体说就是,我们生成8个不同的块,四个90o旋转,四个镜像对90o旋转.转换厚的块通常属于不同的哈稀bucket.例如,对块旋转90o,其hash angle bucket也改变90o,如下图所示:

这里写图片描述

之后又引入blending来保持图像结构信息(高频信息),整个RAISR上采样结构图如下:

这里写图片描述

引入对比度增强,使得可以增强更宽频率范围的图像,结构图如下:

这里写图片描述

之后文章介绍了CT-BASED DOG SHARPENER.

代码理解

github代码:

https://github.com/MKFMIKU/RAISR

训练代码如下:

#! /usr/bin/env python2.7# coding=utf-8import osimport numpy as npimport cv2from scipy.sparse.linalg import cgfrom hashTable import hashTableQangle = 24Qstrenth = 3Qcoherence = 3#构建空的矩阵Q,V用了存对应的LR和HR,h为过滤器 三个hashmap分别为Angle,Strength,Coherence,tQ = np.zeros((Qangle*Qstrenth*Qcoherence,4,11*11,11*11))V = np.zeros((Qangle*Qstrenth*Qcoherence,4,11*11,1))h = np.zeros((Qangle*Qstrenth*Qcoherence,4,11*11))dataDir="/home/qinghua/pythonWork/image_to_image/preprocess/light/origin/"fileList = []for parent,dirnames,filenames in os.walk(dataDir):    for filename in filenames:        fileList.append(os.path.join(parent,filename))for file in fileList:    print("HashMap of %s"%file)    mat = cv2.imread(file)    #转换色彩空间,只对亮度进行训练    mat = cv2.cvtColor(mat, cv2.COLOR_BGR2YCrCb)[:,:,2]    #放缩为0-1    mat = cv2.normalize(mat.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)    HR = mat    #模糊LR    #Upscaling    LR = cv2.GaussianBlur(mat,(0,0),2)    # Set the train map    #遍历每个像素    for xP in range(5,LR.shape[0]-6):        for yP in range(5,LR.shape[1]-6):            #取patch            patch = LR[xP-5:xP+6,yP-5:yP+6]            #计算特征            [angle,strenth,coherence] = hashTable(patch,Qangle,Qstrenth,Qcoherence)            #压缩向量空间            j = angle*9+strenth*3+coherence            A = patch.reshape(1,-1)            x = HR[xP][yP]            #计算像素类型            t = xP%2*2+yP%2            #存入对应的HashMap            Q[j,t] += A*A.T            V[j,t] += A.T*x# Set the train stepfor t in range(4):    for j in range(Qangle*Qstrenth*Qcoherence):       #针对每种像素类型和图像特征训练4*24*3*3个过滤器        h[j,t] = cg(Q[j,t],V[j,t])[0]print("Train is off")np.save("./Filters",h)
阅读全文
0 0