隐藏页面特效
Fork me on GitHub

二维DCT变换 | Python实现

引言

  • 最近专业课在学信息隐藏与数字水印,上到了变换域隐藏技术,提到了其中的DCT变换,遂布置了一个巨烦人的作业,让手动给两个8×8的矩阵做二维DCT变换,在苦逼的算了一小时后,我决定放弃,转而决定写脚本来解决,(̀́)و,正好看网上好像只有matlab的脚本,好像没人用Python来写这个,遂打算搞一个(你就是纯粹为了偷懒不做作业(rǒ)

二维DCT变换原理

  • 还是要普及一下的嘛,毕竟让我头疼了一下午的东西,当然也要好好给你们分享一下啦ԅ(¯﹃¯ԅ)

  • DCT(Discrete Cosine Transform),又叫离散余弦变换,它的第二种类型,经常用于信号和图像数据的压缩。经过DCT变换后的数据能量非常集中,一般只有左上角的数值是非零的,也就是能量都集中在离散余弦变换后的直流和低频部分

  • 1、一维DCT变换
    要弄懂二维离散余弦变换,首先我们需要先了解它在一维下的情况,具体表达式如下:
    F(0)=1Nx=0N1f(x) ...........1
    F(u)=2Nx=0N1f(x)cos(2x+1)uπ2N ...........2
    式中F(u)是第u个余弦变换值,u是广义频率变量,u=1,2,.,N1;f(x)是时域N点序列。x=1,2,.,N1;

  • 2、二维DCT变换
    二维离散余弦变换可由下列表达式表示:
    F(0,0)=1Nx=0N1y=0N1f(x,y) ...........3
    F(0,v)=2Nx=0N1y=0N1f(x,y)cos(2y+1)vπ2N ...........4
    F(u,0)=2Nx=0N1y=0N1f(x,y)cos(2x+1)uπ2N ...........5
    F(u,v)=2Nx=0N1y=0N1f(x,y)cos(2x+1)uπ2Ncos(2y+1)vπ2N ...........6
    6是二维离散余弦变换的正变换公式,其中f(x,y)是空间域一个NN的二维向量元素,即一个NN的矩阵,x,y=0,1,2N1;F(U,V)是经计算后得到的变换域矩阵,u,v=0,1,2.N1.求和可分性是二维离散余弦变换的一个重要特征,因此我们可以用下式表示6
    F(u,v)=2Nx=0N1cos(2x+1)uπ2Ny=0N1f(x,y)cos(2y+1)vπ2N..........7
    由一维和二维的离散余弦变换公式性质可以推导得到二维离散余弦变换也可以写成矩阵相乘形式:
    F=A[f(x,y)AT]..............8

  • A为一维离散余弦变换的变换系数矩阵,ATA的转置矩阵

  • 对图像进行二维离散余弦变换2DDCT的步骤
    1.获得图像的二维数据矩阵f(x,y)
    2.求离散余弦变换的系数矩阵A
    3.求系数矩阵对应的转置矩阵AT
    4.根据公式F=A×[f(x,y)]×AT计算离散余弦变换;

  • 注:公式的大致推导,由于A都是正交阵,所以A1=AT,故Y=A×[f(x,y)]×ATf(x,y)=AT×Y×A=AT×A×[f(x,y)]×AT×A

参考链接:https://www.cnblogs.com/latencytime/p/10228938.html

参考链接:https://blog.csdn.net/allen_sdz/article/details/83279210

Python编程实现

  • 大家注意上述的第8个式子,将变换的两个i=0n转变成了变换矩阵和转置矩阵以及代转换矩阵之间乘积的问题(注意这里的乘是指的叉乘)
  • 遂可以发现DCT后的矩阵应等于A×X×AT
  • 此外,对于x,y同时为0的情况,其参数要单独考虑
  • 大致的思路就是,由于直接计算变换比较繁琐,所以我们就先对于一个单位阵进行操作运算,将其变成一个DCT的变换矩阵,而后在与代算矩阵和转置矩阵叉乘即可。
  • 至此我们就可以着手写脚本了,这里主要是用了两个库numpymath
# -*- coding:utf-8 -*- # Author:Konmu # DCT二维变换 from numpy import array as matrix, arange,zeros,transpose,matmul,ones from math import sqrt,cos,pi ''' 作业代转化矩阵1 a=matrix([[0,255,0,255,0,255,0,255], [255,0,255,0,255,0,255,0], [0,255,0,255,0,255,0,255], [255,0,255,0,255,0,255,0], [0,255,0,255,0,255,0,255], [255,0,255,0,255,0,255,0], [0,255,0,255,0,255,0,255], [255,0,255,0,255,0,255,0]]) ''' a=ones((8,8))#生成单位阵 for i in range(8): a[i]=matrix([128]*8) # 生成全是128的矩阵(作业代转化矩阵2) ''' 测试数据 a=matrix([[61,19,50,20], [82,26,61,45], [89,90,82,43], [93,59,53,97]]) ''' A=zeros((8,8))#生成0矩阵 shape=a.shape[1]#获取维数 for i in range(8): for j in range(8): if(i == 0): x=sqrt(1/shape) else: x=sqrt(2/shape) A[i][j]=x*cos(pi*(j+0.5)*i/shape)#与维数相关 A_T=A.transpose()#矩阵转置 Y1=matmul(A,a)#矩阵叉乘 Y=matmul(Y1,A_T) print(Y) ''' 想要近似值可以尝试这样输出 for i in range(shape): for j in range(shape): print('{:^8.4f}'.format(Y[i][j]),end='\n') print() '''
  • 结果:
    0和255的对称矩阵
    DCT
    128的单元素矩阵
    DCT
    测试矩阵
    DCT

结语

  • ok,完美撒花,结束,交作业喽ヾ(≧O≦)〃嗷~C

__EOF__

本文作者Konmu
本文链接https://www.cnblogs.com/Konmu/p/12555802.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Konmu  阅读(7196)  评论(1编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示