DCT与图像模糊判别

如何使用离散余弦变换评估图像的模糊程度。

DCT与图像模糊判别

有时候问题看上去难以解决也许只是“姿势”不对,换个角度看就会豁然开朗。

什么是DCT

DCT是Discrete Cosine Transform的缩写,即离散余弦变换。简单的说,有限的一连串数可以使用不同频率的余弦信号来叠加表示。例如我们可以将一副图像通过DCT得到其在频域的表达。

DCT与模糊的联系

图像中的犀利边界通常与图像的清晰度联系在一起,而这样的图像在频域则表现为丰富的高频信号。所以我们可以尝试使用图像在频域的信号分布来估算图像的清晰度。

如何使用OpenCV中的DCT

OpenCV提供了DCT的实现。对于二维图像的正变换公式为:

$$ Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T $$

其中的C为:

$$ C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right ) $$

由于输入为二维矩阵,按照公式我们获得的输出将会是一个同等维度的二维矩阵。注意公式中的 $k$ 与 $j$ 分别是图像的行与列数,默认图像的原点在左上角,因此变换后的二维矩阵从左上角到右下角代表的频率逐渐增大。

例如下方这张图像:

原始图像

经过DCT后:

DCT后的结果

接下来我们将使用不同模糊处理方式来获得模糊后的图像,并计算其DCT变换后的数值。用于计算DCT的Python代码:

import cv2
import numpy as np

if __name__ == "__main__":
    img = cv2.imread('/home/robin/Desktop/face.jpg')
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    img_float = np.float32(img)
    dct = cv2.dct(img_float)
    cv2.imshow('dct', dct)
    cv2.waitKey()

高斯模糊

经过高斯模糊后的图像如下:

DCT后的结果如下:

水平运动模糊

经过水平运动模糊后的图像如下:

DCT后的结果如下:

垂直运动模糊

经过垂直运动模糊后的图像如下:

DCT后的结果如下:

实际应用领域DCT

如果想在实际环境下使用DCT来判断图像的模糊状况,我推荐这篇文章:Blur determination in the compressed domain using dct information. 可以在这里找到PDF原文:

https://www.researchgate.net/publication/3835246_Blur_determination_in_the_compressed_domain_using_DCT_information

我尝试在Python下对论文做了实现,如果你感兴趣的话,可以在这里找到。

Reference

封图:Photo by Alex Read on Unsplash

https://en.wikipedia.org/wiki/Discrete_cosine_transform

https://docs.opencv.org/4.0.1/d2/de8/group__core__array.html#ga85aad4d668c01fbd64825f589e3696d4