DCT离散余弦变换及其逆变换+代码

DCT离散余弦变换及其逆变换计算原理如下:



在OPENCV环境下编写DCT变换和逆变换代码:

(只适用于方阵,OPENCV中的cvDCT()函数也只适用于方阵,原因如上述DCT变换原理可知。)

#include "highgui.h"
#include <math.h>
#include <cv.h>
#include "stdlib.h"

void IDCT(CvMat* scr, CvMat *dst);   //逆DCT变换
void DCT(CvMat *scr, CvMat *dst);   //DCT变换


#pragma comment(lib, "opencv_highgui220d.lib") 
#pragma comment(lib, "opencv_core220d.lib") 


void main()
{


double A[3][3]={1,2,3,4,5,6,7,8,9};
CvMat A_Mat=cvMat(3,3,CV_64FC1,A);
CvMat *R_Mat=cvCreateMat(3,3,CV_64FC1);
CvMat *D_Mat=cvCreateMat(3,3,CV_64FC1);


DCT(&A_Mat, R_Mat);
IDCT(R_Mat, D_Mat);


printf("%lf ", cvmGet(R_Mat,2,1));
printf("%lf ", cvmGet(D_Mat,2,1));


system("pause");
}




//DCT变换
void DCT(CvMat *scr, CvMat *dst)
{
int i,j;
double pi=3.141592657;


CvMat *C_Mat=cvCreateMat(scr->height,scr->width,CV_64FC1);
CvMat *CT_Mat=cvCreateMat(scr->height,scr->width,CV_64FC1);


for(j=0; j<C_Mat->height; j++)
{
cvmSet(C_Mat,0,j,sqrtf(2.0/C_Mat->height)*sqrtf(1.0/2));
}


for(i=1; i<C_Mat->height; i++)
for(j=0; j<C_Mat->width; j++)
{
cvmSet(C_Mat,i,j,sqrtf(2.0/C_Mat->height)*cos(pi*(i+i*2*j)/2/C_Mat->height));
}




cvTranspose(C_Mat, CT_Mat);


CvMat *T_Mat=cvCreateMat(scr->height,scr->width,CV_64FC1);


cvMatMul(C_Mat, scr, T_Mat);
cvMatMul(T_Mat,CT_Mat,dst);
}




//逆DCT变换
void IDCT(CvMat *scr, CvMat *dst)
{
int i,j;
double pi=3.141592657;


CvMat *C_Mat=cvCreateMat(scr->height,scr->width,CV_64FC1);
CvMat *CT_Mat=cvCreateMat(scr->height,scr->width,CV_64FC1);


for(j=0; j<C_Mat->height; j++)
{
cvmSet(C_Mat,0,j,sqrtf(2.0/C_Mat->height)*sqrtf(1.0/2));
}


for(i=1; i<C_Mat->height; i++)
for(j=0; j<C_Mat->width; j++)
{
cvmSet(C_Mat,i,j,sqrtf(2.0/C_Mat->height)*cos(pi*(i+i*2*j)/2/C_Mat->height));
}




cvTranspose(C_Mat, CT_Mat);


CvMat *T_Mat=cvCreateMat(scr->height,scr->width,CV_64FC1);


cvMatMul(CT_Mat, scr, T_Mat);
cvMatMul(T_Mat,C_Mat,dst);
}

DCT离散余弦变换)是一种常用的信号分析技术,可以将时域信号转换到频域,常用于图像压缩。下面是 Python 代码实现 DCT 变换和逆变换,并对图像进行压缩和解压缩的示例: ```python import cv2 import numpy as np def dct(img): # 获取图像大小 h, w = img.shape[:2] # 初始化 DCT 系数矩阵 dct_coef = np.zeros((h, w), dtype=np.float32) # 对图像进行 DCT 变换 for i in range(0, h, 8): for j in range(0, w, 8): dct_coef[i:i+8, j:j+8] = cv2.dct(img[i:i+8, j:j+8]) return dct_coef def idct(dct_coef, compress_rate=1.0): # 获取图像大小 h, w = dct_coef.shape[:2] # 计算保留 DCT 系数的数量 num_remain_coef = int(h * w * compress_rate) # 初始化 DCT 系数矩阵 dct_coef_new = np.zeros((h, w), dtype=np.float32) # 选取保留的 DCT 系数 dct_coef_flat = dct_coef.flatten() idx = np.argsort(-np.abs(dct_coef_flat)) dct_coef_flat = dct_coef_flat[idx] dct_coef_flat[num_remain_coef:] = 0 dct_coef_flat = dct_coef_flat[idx.argsort()] dct_coef_new = dct_coef_flat.reshape((h, w)) # 对 DCT 系数进行 IDCT 逆变换 img = np.zeros((h, w), dtype=np.float32) for i in range(0, h, 8): for j in range(0, w, 8): img[i:i+8, j:j+8] = cv2.idct(dct_coef_new[i:i+8, j:j+8]) # 将图像像素范围从 [0, 255] 转换为 [0, 1] img /= 255 return img # 加载图像 img = cv2.imread('lena.png', 0).astype(np.float32) # 进行 DCT 变换 dct_coef = dct(img) # 对 DCT 系数进行压缩,并进行 IDCT 逆变换 compress_rate = 0.1 img_compress = idct(dct_coef, compress_rate) # 显示压缩后的图像 cv2.imshow('compressed image', img_compress) # 等待按下任意按键退出程序 cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,`dct` 函数实现了 DCT 变换,`idct` 函数实现了对 DCT 系数进行压缩和解压缩。在 `idct` 函数中,我们通过计算保留 DCT 系数的数量,将 DCT 系数进行了压缩,并进行 IDCT 逆变换得到压缩后的图像。`compress_rate` 变量控制了压缩比例,压缩比例越高,保留的 DCT 系数数量越少,压缩后的图像质量越低。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值