最近因为工作原因,接触到了超分以及AMD家出的FSR算法,特意记录了解一下~
前言
超分辨率是通过硬件或软件方法提高原有图像分辨率的方法,通过一幅或者多幅低分辨率的图像来得到一幅高分辨率的图像。
FSR是AMD提出的一种超分辨率方法,这种方法不借助深度学习,采用数学推导的方式实现,目前已经更新到3.0版本,本篇博客记录FSR1.0的学习记录。
FSR分为两个阶段,第一阶段为EASU上采样,第二阶段为RCAS锐化。
EASU上采样
首先,解释一下什么是上采样,什么是下采样。
上采样:原先有一张小尺寸的纹理,然后我们将这个纹理放大到大尺寸中(像素变多),然后使用采样方法(例如线性插值)进行填充。
下采样:原先有一张大尺寸的纹理,然后我们将这个纹理缩小到小尺寸中(像素变少),然后使用采样方法填充。
边缘与非边缘的上采样
对图像进行放大时,放大后的像素有两种情况:
- 非边缘:如果是非边缘,则对于放大后的像素点P,在原图对应像素点Q,则Q附近的像素灰度值应该非常接近,此时只需要对Q周围的像素进行加权平均即可,此时权重均为正值。
- 边缘:如果像素点P为边缘,此时应该采用锐化的方式进行处理,对Q附近的像素灰度值采用高频滤波器类似的加权方法进行加权。与上述非边缘的像素不同的是,对边缘像素进行加权计算的权重有负值。
因此,可以将边缘跟非边缘的计算方法统一成一个表达式:
f ( P ) = ∑ i f ( Q i ) H ( Q i ) ∑ i H ( Q i ) \begin{align} f(P) = \frac{\sum_if(Q_i)H(Q_i)}{\sum_iH(Q_i)} \end{align} f(P)=∑iH(Qi)∑if(Qi)H(Qi)
H ( Q i ) H(Q_i) H(Qi):权重计算公式,其应当满足当Q点为非边缘时,权重全为正数,Q点为边缘时,权重会包含负值,用来计算高频滤波器。因此接下来就是要找到满足这样条件的权重计算公式。
Lanczos2 函数
EASU引入了Lanczos函数:
L ( x ) = a s i n ( π x ) s i n ( π x a ) π 2 x 2 , x ∈ [ − a , a ] \begin{align} L(x) = \frac{asin(\pi x)sin(\frac{\pi x}{a})}{\pi^2x^2},x\in [-a, a] \end{align} L(x)=π2x2asin(πx)sin(aπx),x∈[−a,a]
当 a = 2 a = 2 a=2时,通常将其称为Lanczos2函数,EASU就是基于Lanczos2函数作为基础处理的,它的图像如下图所示。
Lanczos2函数的值在 x ∈ [ 0 , 1 ] x \in [0,1] x∈[0,1]时函数值大于0, x ∈ [ 1 , 2 ] x\in [1,2] x∈[1,2]时函数值小于0,符合我们要找的权重函数的要求。但是函数中包含了三角函数,在shader中效率不高,因此EASU用多项式来拟合公式(2)。
L ( x ) = [ 25 16 ( 2 5 x 2 − 1 ) 2 − ( 25 16 − 1 ) ] ( ω x 2 − 1 ) 2 \begin{align} L(x) = \left[ \frac{25}{16}\left( \frac{2}{5}x^2 - 1 \right)^2 - \left( \frac{25}{16} - 1\right) \right](\omega x^2 - 1)^2 \end{align} L(x)=[1625(52x2−1)2−(1625−1)](ωx2−1)2
其中 ω \omega ω参数可以用来控制函数在 x ∈ [ 1 , 2 ] x\in [1,2] x∈[1,2]部分的值,下面是 ω \omega ω从0变化到0.5过程中的函数图像
边缘特征
图像中的边缘,一般有如下几种情况:
EASU主要解决的是阶梯状边缘,因此特征越接近阶梯状边缘,对应的 ω \omega ω应该越小,此时当 x ∈ [ 1 , 2 ] x\in [1,2] x∈[1,2]时, L ( x ) L(x) L(x)返回的权重也越小。
Feature的定义与变量 ω \omega ω
我们为像素T定义Feature的计算公式,只计算像素点T上下左右方向的像素点,该Feature可以与变量 ω \omega ω一一对应。记EASU的边缘特征的中间值为 F F F,它的计算公式为:
F = ( F X 2 + F Y 2 ) \begin{align} F = (FX^2 + FY^2)\end{align} F=(FX2+FY2) F X = ∣ f ( T x − 1 , y − f ( T x + 1 , y ) ∣ m a x ( ∣ f ( T x − 1 , y ) − f ( T x , y ) ∣ , ∣ f ( T x + 1 , y ) − f ( T x , y ) ∣ ) F Y = ∣ f ( T x , y − 1 − f ( T x , y + 1 ) ∣ m a x ( ∣ f ( T x , y − 1 ) − f ( T x , y ) ∣ , ∣ f ( T x , y + 1 ) − f ( T x , y ) ∣ ) FX = \frac{|f(T_{x-1,y} - f(T_{x+1,y})|}{max(|f(T_{x-1,y}) - f(T_{x,y})|, |f(T_{x+1,y}) - f(T_{x,y})|)} \\ FY = \frac{|f(T_{x,y-1} - f(T_{x,y+1})|}{max(|f(T_{x,y-1}) - f(T_{x,y})|, |f(T_{x,y+1}) - f(T_{x,y})|)} FX=max(∣f(Tx−1,y)−f(Tx,y)∣,∣f(Tx+1,y)−f(Tx,y)∣)∣f(Tx−1,y−f(Tx+1,y)∣FY=max(∣f(Tx,y−1)−f(Tx,y)∣,∣f(Tx,y+1)−f(Tx,y)∣)∣f(Tx,y−1−f(Tx,y+1)∣
其中,这里的 f ( x ) f(x) f(x)是 x x x点做过灰度化处理后的颜色值,通过表达式 f = b ∗ 0.5 + r ∗ 0.5 + g f = b * 0.5 + r * 0.5 + g f=b∗0.5+r∗0.5+g 计算。
在公式(4)中, F X , F Y ∈ [ 0 , 1 ] FX,FY \in[0,1] FX,FY∈[0,1],因此 F ∈ [ 0 , 2 ] F\in[0,2] F∈[0,2],为了归一,EASU提出将其映射到 [ 0 , 1 ] [0,1] [0,1]:
F e a t u r e = ( F / 2 ) 2 \begin{align} Feature = (F/2)^2 \end{align} Feature=(F/2)2
我们已经找到了区分边缘的特征值Feature,以及可以通过 ω \omega ω调整区间 [ 1 , 2 ] [1,2] [1,2]取值范围的拟合曲线了,接下来就是要建立Feature跟 ω \omega ω之间的关系。
公式(3)中的函数 L ( x ) , x ∈ [ − 2 , 2 ] L(x),x\in[-2,2] L(x),x∈[−2,2]是关于 y y y轴对称的,因此这里只分析正半轴(EASU里也只用到了正半轴),在正半轴上 L ( x ) L(x) L(x)有三个根: x = 1 ; x = 2 ; x = 1 ω , ( ω > 0 ) x = 1;x = 2;x = \frac{1}{\sqrt{\omega}},(\omega > 0) x=1;x=2;x=ω 1,(ω>0),如下图所示。
当 1 ω ∈ [ 1 , 2 ] \frac{1}{\sqrt{\omega}} \in [1,2] ω 1∈[1,2]时, ( ω ∈ [ 1 4 , 1 ] ) (\omega \in[\frac{1}{4},1]) (ω∈[41,1]),区间 [ 1 , 1 ω ] [1,\frac{1}{\sqrt{\omega}}] [1,ω 1]中有一个极小值 m m m。
- 1 ω → 1 : m → 0 \frac{1}{\sqrt{\omega}} \rightarrow 1: m \rightarrow 0 ω 1→1:m→0
- 1 ω → 2 : m → − 2187 16483 \frac{1}{\sqrt{\omega}} \rightarrow 2: m \rightarrow -\frac{2187}{16483} ω 1→2:m→−164832187
注意到当 1 ω ∈ [ 1 , 2 ] \frac{1}{\sqrt{\omega}} \in [1,2] ω 1∈[1,2]时, x ∈ [ 1 ω , 2 ] x\in[\frac{1}{\sqrt{\omega}}, 2] x∈[ω 1,2]区间出现了一个负的Lobe部分,为了解决这个问题,EASU进行了截断,只取 x ∈ [ 0 , 1 ω ] x\in [0,\frac{1}{\sqrt{\omega}}] x∈[0,ω 1]区间。
因此可以通过改变 1 ω \frac{1}{\sqrt{\omega}} ω 1的值来控制 [ 1 , 1 ω ] [1,\frac{1}{\sqrt{\omega}}] [1,ω 1]区间里负值的大小(用来作公式(1)中的负权重)。
ω = 1 − 3 4 F e a t u r e \begin{align} \omega = 1 - \frac{3}{4}Feature \end{align} ω=1−43Feature
但是由于 1 ω \frac{1}{\sqrt{\omega}} ω 1在趋近于1时,负权重不够,会导致边缘信息识别不足,因此EASU将 1 ω \frac{1}{\sqrt{\omega}} ω 1的范围限定在 [ 2 , 2 ] [\sqrt{2},2] [2 ,2],因此 ω ∈ [ 1 4 , 1 2 ] \omega \in[\frac{1}{4}, \frac{1}{2}] ω∈[41,21],得出新的线性关系:
ω = 1 2 − 1 4 F e a t u r e \begin{align} \omega = \frac{1}{2} - \frac{1}{4}Feature \end{align} ω=21−41Feature
EASU同时限定了 x x x的范围为 x ∈ [ 0 , 1 ω ] x\in[0, \frac{1}{\sqrt{\omega}}] x∈[0,ω 1],即 x = m i n ( x , 1 ω ) x=min(x,\frac{1}{\sqrt{\omega}}) x=min(x,ω 1)。
Feature获得
EASU计算 Q Q Q点特征时,采用的是采样像素点 Q Q Q周围12个像素的值来计算。EASU首先会进行批量采样,从而获取 Q Q Q周围像素的像素值,待采样的像素如下图所示(标识为z的像素点为多余的像素,在计算时不会用到):
每次使用Gather4指令批量采样4个像素点中的一个通道,例如浅绿色框采样的顺序是ijfe,因为像素有三个通道RGB,因此每次批量采样 4 * 3 次。
然后,计算特征时,分四组分别计算出4个Feature。
使用双线性插值得到最终的Feature。如下图所示, O = f l o o r ( Q ) O = floor(Q) O=floor(Q), u 、 v u、v u、v则是 Q Q Q到 O O O的偏移。
F e a t u r e = ( 1 − u ) ( 1 − v ) f 1 + u ( 1 − v ) f 2 + u v f 3 + ( 1 − u ) v f 4 \begin{align} Feature = (1-u)(1-v)f_1 + u(1-v)f_2+uvf_3+(1 - u)vf_4 \end{align} Feature=(1−u)(1−v)f1+u(1−v)f2+uvf3+(1−u)vf4
结合公式(7)和公式(8),便可计算出 ω \omega ω的值。
梯度
计算Feature的同时,EASU还计算了 Q Q Q点的像素灰度变化的梯度,同样也是分四组计算梯度,最后用双线性插值得出最终的梯度向量。每组梯度计算的方式如下:
D x = g − e = f ( Q x + 1 , y ) − f ( Q x − 1 , y ) D y = j − b = f ( Q x , y + 1 ) − f ( Q x , y − 1 ) D_x = g - e = f(Q_{x+1,y}) - f(Q_{x-1,y})\\ D_y = j - b = f(Q_{x,y+1}) - f(Q_{x,y-1}) Dx=g−e=f(Qx+1,y)−f(Qx−1,y)Dy=j−b=f(Qx,y+1)−f(Qx,y−1) D ⃗ = ( c o s θ , s i n θ ) = ( D x D x 2 + D y 2 , D y D x 2 + D y 2 ) \begin{align} \vec D = (cos\theta,sin\theta) = (\frac{D_x}{\sqrt{D_x^2 + D_y^2}}, \frac{D_y}{\sqrt{D_x^2 + D_y^2}}) \end{align} D =(cosθ,sinθ)=(Dx2+Dy2 Dx,Dx2+Dy2 Dy)
采样颜色值
到这里,我们得到了 Q Q Q的梯度,以及Feature,之后,EASU分别对 Q Q Q周围的12个像素,按照梯度角度进行旋转,并进行缩放,最终利用像素点左上角到 Q Q Q点的欧式距离作为 x x x,带入权重公式,即公式(3),得到周围像素的权重。
如上图,像素b跟 Q Q Q之间的向量 Q B ⃗ \vec{QB} QB 按照梯度旋转:
x r = x Q B ∗ c o s θ + y Q B ∗ s i n θ y r = − x Q B ∗ s i n θ + y Q B ∗ c o s θ \begin{align} x_r &= x_{QB} * cos\theta + y_{QB}* sin\theta \notag \\ y_r &= -x_{QB} * sin\theta + y_{QB}*cos\theta \end{align} xryr=xQB∗cosθ+yQB∗sinθ=−xQB∗sinθ+yQB∗cosθ
旋转完毕后,EASU定义了一个将旋转向量根据梯度 和边缘特征 进行缩放的公式(注意,这里是直接定义的公式,并没有数学逻辑):
S t r e t c h = 1 m a x ( ∣ s i n θ ∣ , ∣ c o s θ ∣ ) S x = 1 + ( S t r e t c h − 1 ) ∗ F e a t u r e S y = 1 − 0.5 ∗ F e a t u r e \begin{align}Stretch &= \frac{1}{max(|sin\theta|,|cos\theta|)}\\ S_x &= 1 + (Stretch - 1) * Feature \notag \\ S_y &= 1 - 0.5 * Feature \notag \end{align} StretchSxSy=max(∣sinθ∣,∣cosθ∣)1=1+(Stretch−1)∗Feature=1−0.5∗Feature
然后得出 Q B ⃗ \vec{QB} QB 旋转缩放后的向量坐标:
S x b = x r ∗ S x , S y b = y r ∗ S y \begin{align}S_{xb} = x_r * S_x,S_{yb} = y_r * S_y\end{align} Sxb=xr∗Sx,Syb=yr∗Sy
最后求出向量的模:
d b = m i n ( S x b 2 + S y b 2 , 1 ω ) \begin{align}d_b = min(\sqrt{S_{xb}^2 + S_{yb}^2}, \frac{1}{\sqrt\omega})\end{align} db=min(Sxb2+Syb2 ,ω 1)
将得出的 d b d_b db带入到公式(3),即可求出b像素点的权重值。其他像素点一次按照这样的方式求出对应像素的权重值,最后利用公式(1),即可求出上采样 P P P点的像素值。
EASU里最后会对求出的颜色做限制,限制颜色的最大最小值只能在这12个采样点颜色之间,据说可以减少ringing效果。
RCAS锐化
上采样结束后,FSR最后对上采样得到的图像进行一次RCAS(Robust Contrast Adaptive Sharpening在CAS基础上进行改进)的锐化处理,将边缘信息进一步加强,RCAS其实是拉普拉斯算子的变种:
最后像素 P P P按照上面的算子进行加权计算即可:
F ( P ) = f ( P ) + ω ∗ ( f ( P x − 1 , y ) + f ( P x + 1 , y ) + f ( P x , y − 1 ) + f ( P x , y + 1 ) ) 4 ω + 1 \begin{align}F(P) = \frac{f(P) + \omega * (f(P_{x-1,y}) + f(P_{x+1,y}) + f(P_{x,y-1}) + f(P_{x,y+1}))}{4\omega + 1}\end{align} F(P)=4ω+1f(P)+ω∗(f(Px−1,y)+f(Px+1,y)+f(Px,y−1)+f(Px,y+1))
对于 ω \omega ω权重,RCAS计算方法是获取像素 P P P点周围的四个像素,然后根据包括 P P P在内五个像素点的最大最小值来计算。
于是有
ω = m a x ( − M i n 4 M a x , 1 − M a x 4 M i n − 4 ) ∗ S c a l e \begin{align}\omega = max(-\frac{Min}{4Max},\frac{1 - Max}{4Min - 4}) * Scale\end{align} ω=max(−4MaxMin,4Min−41−Max)∗Scale
Scale为采样之后分辨率跟原分辨率的比值。
RCAS中为了确保 ω \omega ω为负数,最后对 ω \omega ω做了限制:
ω = m a x ( − ( 1 4 − 1 16 ) , m i n ( ω , 0 ) ) \begin{align}\omega = max(-(\frac{1}{4} - \frac{1}{16}), min(\omega,0))\end{align} ω=max(−(41−161),min(ω,0))
对于RGB每个通道,都计算一次对应的 ω R 、 ω G 、 ω B \omega_R、\omega_G、\omega_B ωR、ωG、ωB。
总结
参考这份github上用python实现的FSR,可以实现超分效果,如下图所示:
总结一下,FSR一共包含两个阶段,第一阶段为EASU上采样,第二阶段为RCAS锐化,其中EASU上采样是重点。
EASU的基本思想是根据像素点周围颜色变化的梯度,计算出一个可变的权重函数,将周围点加权得出当前像素点的颜色。其中,当该点处于边缘时,权重函数会出现负值,起到一个类似锐化的效果,用于突出边缘像素;当该点处于非边缘时,权重函数全为正值,起到一个类似平均池化的效果。