图像的离散余弦变换
离散余弦变换是以一组不同频率和幅值的余弦函数和来近似一幅图像,实际上是傅里叶变换的实数部分。
一维的离散余弦变换
1.正变换:
对于时间序列分f(x),其中,x=0,1,2....N-1,其一维离散余弦变换为:
2.逆变换:
一维离散余弦逆变换为:
通过上面的一维离散余弦变换,我们可以推广成二维(M*N的图像)离散余弦变换,下面我们来重点学习二维离散余弦变换。
二维离散余弦变换
1.正变换:
2.逆变换:
二维离散余弦变换的逆变换为:
矩阵形式表示为:
[F(u,v)]=[A][f(x,y)][A]T 正变换
[f(x,y)]=[A]T[F(u,v)][A] 逆变换
matlab自带函数dct2()实现离散余弦变换
由于我是对图像进行的操作,所以下面我仅仅对二维离散余弦变换作分析及代码的实现。
I=imread('F:\模式识别\coins.png');
I=im2double(I);
J=dct2(I); %二维离散余弦变换
figure;
subplot(121);imshow(I);
subplot(122);imshow(J);
编程实现dct2的功能
参考:[转载]使用Matlab实现离散余弦变换(DCT)
网址:http://blog.sina.com.cn/s/blog_9b81c6df010107ai.html
%通过矩阵形式实现离散余弦变换,Y=M*X*N'
%参数:X是二维图像矩阵,Y是变换后的系数矩阵
function Y = dct21(X)
[m,n] = size(X);
FM = zeros(m,m);
FN = zeros(n,n);
for i = 0:m-1
for j = 0:m-1
if i == 0
FM(i+1,j+1) = sqrt(1/m)*cos(((2*j+1)*i*pi)/(2*m));
else
FM(i+1,j+1) = sqrt(2/m)*cos(((2*j+1)*i*pi)/(2*m));
end
end
end
for i = 0:n-1
for j = 0:n-1
if i == 0
FN(i+1,j+1) = sqrt(1/n)*cos(((2*j+1)*i*pi)/(2*n));
else
FN(i+1,j+1) = sqrt(2/n)*cos(((2*j+1)*i*pi)/(2*n));
end
end
end
X = double(X); %注意变换后的矩阵数据类型为double
Y = FM*X*FN';
命令窗口中输入:
Y = dct21(I)
imshow(Y)
正变换的两种实验结果比较
统一都对coins.png这幅图像进行测试:
Matlab自带的dct2()函数运行结果:
编程实现dct21(正变换)的结果:
最后对比两种结果:
在命令窗口中输入:a=J-Y<0.01,即判断J与Y的误差是否在0.01的范围内,结果显示全部为1,则误差均在0.01的范围内。
离散余弦的逆变换实现图像复原
1.自带的函数:idct2();
即在命令窗口中输入a=idct2(J),即可得到复原的图像。
2.编写的dct22(逆变换)程序:
function Y = dct22(X)
[m,n] = size(X);
FM = zeros(m,m);
FN = zeros(n,n);
for i = 0:m-1
for j = 0:m-1
if i == 0
FM(i+1,j+1) = sqrt(1/m)*cos(((2*j+1)*i*pi)/(2*m));
else
FM(i+1,j+1) = sqrt(2/m)*cos(((2*j+1)*i*pi)/(2*m));
end
end
end
for i = 0:n-1
for j = 0:n-1
if i == 0
FN(i+1,j+1) = sqrt(1/n)*cos(((2*j+1)*i*pi)/(2*n));
else
FN(i+1,j+1) = sqrt(2/n)*cos(((2*j+1)*i*pi)/(2*n));
end
end
end
X = double(X); %注意变换后的矩阵数据类型为double
Y = FM'*X*FN; %实现DCT逆变换仅仅将本行换为Y = FM'*X*FN即可
复原的图:
参考资料:
1.MATLAB图像处理实例详解
2.http://blog.sina.com.cn/s/blog_9b81c6df010107ai.html([转载]使用Matlab实现离散余弦变换(DCT))。
3.http://blog.csdn.net/luoweifu/article/details/8214959