使用DCT将图像分解为两个频率分量?

May*_*ari 2 matlab colors image-processing

我是数字图像处理领域的初学者,最近我正在开展一个项目,我必须使用DCT将图像分解成两个频率分量(低和高).我在网上搜索了很多,我发现MATLAB有一个用于Discrete Cosine Transform的内置函数,它的用法如下:

dct_img = dct2(img);
Run Code Online (Sandbox Code Playgroud)

img输入图像在哪里,结果dct_img是DCT img.

我的问题是,"我如何将dct_img分解为两个频率分量,即低频和高频分量".

mbs*_*kel 12

正如你所提到的,dct2并将idct2为你完成大部分工作.那么剩下的问题是:什么是高频,什么是低频内容?二维变换之后的系数实际上将代表两个频率(一个在x方向,一个在y方向上).下显示了8x8 离散余弦变换中每个系数的基数:

因此,低和高的问题可以用不同的方式回答.如上所示,在JPEG编码中使用的常见方式从零频率向下对角线进行.正如我们在下面的示例中看到的那样,主要是因为自然图像主要位于"低"频率的"左上角".当然值得研究一下dct2你所在地区的实际选择的结果和高低.

在下面我将对角线划分光谱并绘制DCT系数 - 以对数刻度,否则我们只能看到一个大的峰值(1,1).在示例中,我正在切割远远超过系数的一半(可调节cutoff),我们可以看到高频部分("HF")仍然包含一些相关的图像信息.如果设置cutoff0或低于,则仅留下小振幅的噪声.

结果

%// Load an image
Orig = double(imread('rice.png'));
%// Transform
Orig_T = dct2(Orig);
%// Split between high- and low-frequency in the spectrum (*)
cutoff = round(0.5 * 256);
High_T = fliplr(tril(fliplr(Orig_T), cutoff));
Low_T = Orig_T - High_T;
%// Transform back
High = idct2(High_T);
Low = idct2(Low_T);

%// Plot results
figure, colormap gray
subplot(3,2,1), imagesc(Orig), title('Original'), axis square, colorbar 
subplot(3,2,2), imagesc(log(abs(Orig_T))), title('log(DCT(Original))'),  axis square, colorbar

subplot(3,2,3), imagesc(log(abs(Low_T))), title('log(DCT(LF))'), axis square, colorbar
subplot(3,2,4), imagesc(log(abs(High_T))), title('log(DCT(HF))'), axis square, colorbar

subplot(3,2,5), imagesc(Low), title('LF'), axis square, colorbar
subplot(3,2,6), imagesc(High), title('HF'), axis square, colorbar
Run Code Online (Sandbox Code Playgroud)

(*)注意tril:下三角函数相对于从左上角到右下角的数学对角线操作,因为我想要另一个对角线,我在前后左右翻转.

还要注意,这种操作通常不适用于整个图像,而是应用于例如8x8的块.看看blockproc这篇文章.

  • 良好的数字和非常好的代码实现.+1 (2认同)
  • @MayankTiwari:从概念上讲,这与图像大小无关,特别是如果你操作上一句中提到的子块:那么你只需要把它制成'm*n`个方块子块,这样就可以了= K*m,N = K*n`.但是,具体的代码是作为插图编写的,可能不适用于一般情况.这是你提问的原因吗? (2认同)