小张学算法之基础算法:4.DCT变换

DCT变换,离散余弦变换,将时域/空间域转换到频域上。是DFT离散的傅里叶变换去掉虚数项的表示。常用于图像音频压缩技术上,如jpeg,h264,mpeg算法中。DCT变换后可以将高频的信号通过量化等方式去掉,以实现压缩,因为高频信号往往是人们不关注的,或者影响很小。

DCT变换就是限定了输入信号的DFT(离散傅里叶)变换,输入信号是实偶信号

一维DCT变换:

在这里插入图片描述
推导与理解见知乎:

https://zhuanlan.zhihu.com/p/85299446

二维DCT变换:

二维DCT变换无非是一维多了一个分量而已,公式是相同的。
在这里插入图片描述
矩阵表示和matlab程序
DCT变换有高度的对称性,用矩阵表示:
在这里插入图片描述
matlib代码:

clear;
clc;
X=[
    61    19    50    20
    82    26    61    45
    89    90    82    43
    93    59    53    97] %原始的数据
A=zeros(4);
for i=0:3
    for j=0:3
        if i==0
            a=sqrt(1/4);
        else
            a=sqrt(2/4);
        end
        A(i+1,j+1)=a*cos(pi*(j+0.5)*i/4); %生成变换矩阵
    end
end
Y=A*X*A'   %DCT变换后的矩阵
X1=A'*Y*A  %DCT反变换恢复的矩阵

逆变换公式:
在这里插入图片描述
在这里插入图片描述
c代码:

#include <stdio.h>
#include <math.h>
#include <stdio.h>

/*
* params: 
in: in_matrix, input matrix to transfer
	line_num: line
	row_num: row
out: out_dct
*/
void dct_transfer(float **out_dct, float **in_matrix, int line_num, int row_num)
{
	float c_u = 0;
	float c_v = 0;
	for (int u = 0; u < line_num; u++)
	{
		for (int v = 0; v < row_num; v++)
		{
			out_dct[u][v] = 0;
			// calc sum
			for (int x = 0; x < line_num; x++)
			{
				for (int y = 0; y < row_num; y++)
				{
					out_dct[u][v] += in_matrix[x][y] *cos(M_PI/((float)line_num) *(x + 0.5)*u) * cos(M_PI/ ((float)row_num)* (y+0.5) *v); 
				}
			}

			c_u = (u==0? sqrt(1.0/line_num) : sqrt(2.0/line_num));
        	c_v = (u==0? sqrt(1.0/row_num) : sqrt(2.0/row_num));
  			out_dct[u][v] = c_u * c_v * out_dct[u][v];
		}
	}
}

void idct_transfer(float **out_matrix, float **in_dct, int line_num, int row_num)
{
	float c_u = 0;
	float c_v = 0;
	for (int i = 0; i < line_num; i++)
	{
		for (int j = 0; j < row_num; j++)
		{
			out_matrix[i][j] = 0;
			for (int u = 0; u < line_num; u++)
			{
				for (int v =0; v < row_num; v++)
				{
					c_u = (u==0? sqrt(1.0/line_num) : sqrt(2.0/line_num));
        			c_v = (u==0? sqrt(1.0/row_num) : sqrt(2.0/row_num));
  					out_matrix[i][j] += c_u * c_v* in_dct[u][v] * cos(M_PI/((float)line_num) *(x + 0.5)*u) * cos(M_PI/ ((float)row_num)* (y+0.5) *v)
				}
			}

		}
	}
}

分块DCT变换

在图像处理中,一张图的数据很大,需要将其分块处理,比如h264,就将图分为1616或88的宏块,然后再进行DCT变换,然后进行量话,Z型编码,熵编码等操作。随着子块变大,算法的复杂度会急剧上升。

https://www.cnblogs.com/wyuzl/p/7880124.html

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值