任意一幅图片,都可以转化为傅里叶频谱图,从空域转化为频域。本文的目的是想通过对图像的傅里叶频谱数据处理,得到其细节保留的信息,从而对画质评价提供数据参考。
一、频谱图的获取
1.将RGB图转化为Gray图
2.进行float32形式转换
float32_img = np.float32(img)
3.使用cv2.dft进行傅里叶变化
dft_img = cv2.dft(float32_img, flags=cv2.DFT_COMPLEX_OUTPUT)
4.使用np.fft.shiftfft()将变化后的图像的低频转移到中心位置
dft_img_ce = np.fft.fftshift(dft_img)
5.使用cv2.magnitude将实部和虚部转换为实部,乘以20是为了使得结果更大
img_dft = 20 * np.log(cv2.magnitude(dft_img_ce[:, :, 0], dft_img_ce[:, :, 1]))
6.进行画图操作
获得细节保留的处理方法是:
利用傅里叶频谱图的对称性将所有同样频率的强度都加起来得到一个数组amp,而后利用row形成一个频率分布f,最后,利用数组amp与频率分布f的关系, 得到细节保留值Detail Reserve。
二、从频谱图中提取频域信息
1.利用傅里叶频谱图的对称性将所有同样频率的强度都加起来得到一个数组amp:以对角线为最大半径,所有点的半径都与对角线做比例,然后乘以行数Row,投影到以Row为半径的数组上。(这里注意因为坐标关系,要对比例做一些转换,先加0.5,再减去1)
freq[r - 1][c - 1] = int(1.0 * math.sqrt(r * r + c * c) / maxVal * nbins + 0.5) - 1 #算出任意一个半径位置对应在row的点位(有可能不同的半径位置在row的点位是相同的)
ind = freq[r - 1][c - 1]
amp[0][ind] = amp[0][ind] + mtfImg[r - 1][c - 1] #此点位的频率强度,在对应的row上进行叠加。
得到一个一维数组amp[0]
2.利用row形成一个频率分布轴。
f = 1.0 * np.array(range(nbins))/nbins * math.sqrt(0.5) #也是一个一维数组,数组的长度与amp[0]一样。
三、计算细节保留值
利用数组amp与频率分布f的关系,得到细节保留值Detail Reserve。
1.先根据f,计算出一个CSF值(对比度感知函数):csf=1.0 * a * math.pow(v, c) * math.exp(-1.0 * b * v)/K, CSF也是和f、amp[0]长度一样的数组
2.DR=np.sum(amp * csf)/np.sum(csf)
运行结果:
mpSpatialImg.shape: 953 967
len(amp[0]):447
amp[0]:
[3.24382395e-01 1.68568522e+00 2.40568510e+00 4.86635603e+00
4.23052636e+00 6.35914639e+00 6.24597985e+00 8.25076395e+00
... ....
1.22420089e+01 9.83440375e+00 7.27015185e+00 4.70952785e+00
2.47337472e+00]
f[]:
[0. 0.0014824 0.00296481 0.00444721 0.00592962 0.00741202
0.00889442 0.01037683 0.01185923 0.01334164 0.01482404 0.01630645
......
0.69376514 0.69524755 0.69672995 0.69821236 0.69969476 0.70117716
0.70265957 0.70414197 0.70562438]
len(f): 447
DetailReserve: 221.04386677718333