数字图像处理 --- 图像的离散余弦变换(python实战)

news2025/1/15 12:47:03

图像的离散余弦变换(python实战)

        这篇文章是我上两篇文章的延续,主要是觉得前面的文章太长了,所以把关于图像的DCT变换部分单独拎出来放到这里,这两篇文章分别是:

1,一维DCT

数字信号处理 --- 一维离散余弦变换(python实战)_python 离散余弦变换-CSDN博客文章浏览阅读318次,点赞6次,收藏10次。本文详细介绍了基于python实现的一维离散余弦变换,是我个人的学习笔记。_python 离散余弦变换https://blog.csdn.net/daduzimama/article/details/140449135

2,二维DCT

数字信号处理 --- 二维离散余弦变换(python实战)-CSDN博客文章浏览阅读954次,点赞22次,收藏11次。在我的前一篇文章的基础上,本文详细的介绍了二维DCT,并以图像的DCT举例。https://blog.csdn.net/daduzimama/article/details/140780627

正文:

图像的离散余弦变换

正变换

定义图像DCT正变换与反变换的函数

def ImagePadding(x):
    [M,N]=x.shape
    
    # 定义零填充的大小
    pad_height = (8 - M % 8) % 8
    pad_width = (8 - N % 8) % 8

    # 对图像进行零填充
    padded_x = np.pad(x, ((0, pad_height), (0, pad_width)), mode='constant', constant_values=0)
    return padded_x


def DCT2D_block(x):
    #image padding
    x_pad=ImagePadding(x)
    print("padded image size=",x_pad.shape)
    N=x_pad.shape[0]//8
    
    #display padded image
    plt.figure(figsize=(6, 6))
    plt.imshow(x_pad,cmap='gray')
    plt.title('Padded Image')
    
    #build dct transform matrix
    A=DCT1d_matrix(8)
    AT=A.T
    print("DCT Transform Matrix for N = 8:",A)
    
    #分块
    block8x8=np.zeros((8,8))
    X=np.zeros((x_pad.shape))
    for i in range(N):
        for j in range(N):
            for x in range(8):
                for y in range(8):
                    block8x8[x,y]=x_pad[i*8+x,j*8+y]
            X8x8=A@block8x8@AT
            for p in range(8):
                for q in range(8):
                    X[i*8+p,j*8+q]=X8x8[p,q]                   
    return X

def DCT2D(x):
    #image padding
    x_pad=ImagePadding(x)
    print("padded image size=",x_pad.shape)
    
    #display padded image
    plt.figure(figsize=(6, 6))
    plt.imshow(x_pad,cmap='gray')
    plt.title('Padded Image')
    
    #build dct transform matrix
    A=DCT1d_matrix(x_pad.shape[0])
    AT=A.T
    
    #DCT
    X=A@x_pad@AT
    
    return X

def IDCT2D(X):
    #check
    if not(X.shape[0]==X.shape[1]):
        print("Err:this image is not squre")
        return
    
    #build dct transform matrix
    A=DCT1d_matrix(X.shape[0])
    AT=A.T
    
    #IDCT
    x=AT@X@A
    
    return x

图像DCT正变换的例子,导入测试图像

from skimage import data
#load image
Img = data.astronaut()
print(Img.shape)

plt.figure(figsize=(3, 3))
plt.imshow(Img,cmap='gray')
plt.title('Astronaut')

        分别用自己定义的函数和scipy库自带的函数对图像进行二维DCT运算,其中库函数用于验证我自己写的DCT函数的运行结果是否正确。

#调用自己定义的函数
Img_DCT=DCT2D(Img)
fig=plt.figure(figsize=(3,3))
plt.imshow(Img_DCT,cmap='gray')
#调用scipy库函数
dctlib=dct(dct(Img.T, norm='ortho').T, norm='ortho')
fig=plt.figure(figsize=(3,3))
plt.imshow(dctlib,cmap='gray',vmin=np.min(dctlib), vmax=np.max(dctlib))
print("my result:",Img_DCT)
print("result of lib:",dctlib)

 运行结果如下:

        整幅图像的DCT变换结果像是一张全黑的图,这是由于DCT系数只在左上角的很小一块区域的数值较大,而其他大部分区域都是很小的值,让人看起来就像是一幅全黑的图像。在后面的文章中,我打算只对整幅图像中的一小块内容做DCT变换,便于更好的演示。在演示之前,我们先看看图像DCT的反变换。


反变换 

Img_idct=IDCT2D(Img_DCT)
fig=plt.figure()
plt.subplot(1,2,1)
plt.imshow(Img,cmap='gray')
plt.title('Org image')

plt.subplot(1,2,2)
plt.imshow(Img_idct,cmap='gray')
plt.title('Inv dct image')

 运行结果如下:


一小块图像的DCT正变换与反变换 

从图像中截取一小段图片,并对他进行二维DCT:

tiny = Img[20:28, 30:38]    # a tiny 8 x 8 block, in the color=0 (Red) channel

fig=plt.figure()
plt.imshow(tiny)
plt.colorbar()

# And here are the numbers.
print("tiny:\n",tiny)

 运行结果,这是原图中截取的一小段:

#2d dct of tiny
tiny_dct=DCT2D(tiny)

fig=plt.figure()
plt.imshow(tiny_dct)
plt.colorbar()

np.set_printoptions(linewidth=100) # output line width (default is 75)
round6 = np.vectorize(lambda m: '{:6.1f}'.format(m))
round6(tiny_dct)

        这是与之对应的DCT结果,在二维DCT除了左上角(对应最低频率cos函数的系数,即,直流分量)以外,大量的DCT系数都很小,且越是接近左下角(对应频率最高的cos函数的系数)越是接近于0:

如果要压缩图像的话,可以把部分高频dct系数置0,以达到压缩的目的:

# First make a copy to work on.
tinyDCT_chopped = tiny_dct.copy()
N=tinyDCT_chopped.shape[0]
# Then zero the pieces below the x + y = 8 line.
for x in range(N):
    for u in range(N):
        if x + u > 8:
            tinyDCT_chopped[x,u] = 0.0

fig=plt.figure()
plt.imshow(tinyDCT_chopped)
plt.colorbar()

round6(tinyDCT_chopped)

将压缩前后的小图进行对比,可以看到虽然我在上面对大量的高频DCT系数采取了置0操作,但反变换回去后的图像和原图相差无几:

#将压缩前后的小图像进行对比
tiny_zip=IDCT2D(tinyDCT_chopped)

fig=plt.figure()
plt.subplot(1,2,1)
plt.imshow(tiny,cmap='gray')
plt.title('Org image')

plt.subplot(1,2,2)
plt.imshow(tiny_zip,cmap='gray')
plt.title('compressed image')

运行结果:


 (全文完)

作者 --- 松下J27

 参考文献:

1,《数字图像处理技术详解与Visual C++实践》---左飞

2,dct — SciPy v1.14.0 Manual

3,dct

4,https://en.wikipedia.org/wiki/Discrete_cosine_transform

5,https://en.wikipedia.org/wiki/Cross-correlation

6,Amplitude, Period, Phase Shift and Frequency

版权声明:文中的部分图片,文字或者其他素材,可能来自很多不同的网站和说明,在此没法一一列出,如有侵权,请告知,立即删除。欢迎大家转载,但是,如果有人引用或者COPY我的文章,必须在你的文章中注明你所使用的图片或者文字来自于我的文章,否则,侵权必究。 ----松下J27 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1968343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搜维尔科技:【研究】Haption的自动识别技术

Real-Time Interaction for Delmia Human RTID Human “Real-Time Interaction for Delmia Human” 是个附加在Delmia V5™上的软件,它能让使用者使用数字人体模型在虚拟环境中进行实时互动仿真 在Delmia 中使用RTI ,使用者可以模拟进行以下研究: 1. 可…

table car vs. table cars:数据库命名用单数还是复数?

数据库的命名方式已经形成了许多共识,比如全部小写、下划线分隔、使用标准缩写等;其中就包括「使用单数名词」。 用户 jonr 在 reddit 网的程序员笑话(ProgrammerHumor)社区发了一篇帖子,调侃这些数据库命名方式的共识…

突破csdn每日15篇文章限制的方法

买一个vip年会员248元,就可以了.......

Linux-3:Shell编程——基础语法(0-50%)

目录 前言 一、变量 1.定义变量 2.使用变量 3.修改变量 4.将命令的结果赋值给变量 5.只读变量 6.删除变量 二、传递参数 三、字符串 1.字符串举例 2.统计字符串长度 3.字符串拼接 4.截取字符串 总结 前言 Shell是一种程序设计语言。作为命令语言,它…

算法学习day26

滑动窗口系列题 一、替换后的最长重复子串 给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符,并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。 在执行上述操作后,返回 包含相同字母的最长子字符串的长度。 输入&#xff1a…

MySQL--MySQL函数

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 MySQL函数 一、MySQL函数简介 函数表示对输入参数值返回一个具有特定关系的值,MSOL提供了大量丰富的函数,在进行数据库管理以…

CTFHub——XSS全系列

1、反射型: 发现为表单式,猜测哪个可能存在注入漏洞,分别做测试注入发现name框存在xss漏洞 输入发现有回显但不是对方cookie,参考wp发现要用xss线上平台 将xss平台测试语句注入,将得到的url编码地址填入url框&#xf…

Mongodb集合操作

文章目录 1、进入容器2、如果数据库不存在,则创建数据库,否则切换到指定数据库3、在 MongoDB 中,创建集合不是必须操作。当你插入一些文档时,MongoDB 会自动创建集合。4、查看数据库列表5、查看集合6、显示创建集合7、删除集合 1、…

Raspberry Pi Docker 运行 IRIS

在 Raspberry Pi 上成功安装 Docker 后可以安装 IRIS 数据库。 安装的命令为: docker run --name my-iris -d --publish 1972:1972 --publish 52773:52773 intersystems/irishealth-community:latest-em-linux-arm64v8 注意,我们这里暴露了 2 个端口&a…

Spring框架 配置Gateway网关/spring cloud gateway 基础入门案例教程

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 网关作为微服务集群唯一的对外入口,可以实现很多功能. 例如: 统一的解决跨域(一个ajax请求 origin域名和请求目标url中域名不同,ip不同,域名不同,端口不同,都会引发的问题)问题. 统一的身份认证.认证解…

OpenStack Yoga版安装笔记(十)placement练习

1、练习场景说明 在OpenStack Yoga版安装笔记(九)中,placement已经在controller node虚拟机上安装完成,并且已经成功拍摄了快照。 此时,controller node虚机已经安装了keystone、keystone DB、glance、glance DB、Open…

反序列化漏洞vulhub靶场serial

环境搭建 下载 https://download.vulnhub.com/serial/serial.zip 解压出来就是这种 你会得到一个这样的文件,这里使用VMware新建一个虚拟机,这里记录比较重要的几部分。 这里就是使用我们刚才下过来的。 漏洞过程详解 1.信息收集 打开靶机&#xff0…

干货满满,从零到一:编程小白如何在大学成为编程大神?

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

Git(4) 解决Git相关问题的实用技巧

本文将介绍一些Git实用的技巧,实际操作中解决常见的Git问题。 问题1:将本地项目推送到远程仓库 如何将本地项目推送到远程仓库,包括处理常见错误的方法,并最终将代码推送到 main 分支。 步骤 1. 初始化本地仓库 确保已经在本地…

类和对象的深入了解6

1.初始化列表 初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括 号中的初始值或表达式。 class Date { public:Date(int year, int month, int day): _year(year), _month(month),…

Cellpress|单细胞文章|单细胞转录和大队列食管癌免疫治疗

新辅助免疫检查点阻断 (ICB) 在可手术食管鳞状细胞癌 (ESCC) 中显示出希望,但缺乏可用的疗效生物标志物。该文章对接受新辅助 ICB 的 ESCC 患者的肿瘤进行单细胞 RNA 测序,发现一组表达SPRY1 (CD8 Tex-SPRY1) 的耗竭 CD8 T 细胞亚群,其显示…

72.结构体变量直接赋值

目录 一.结构体变量直接赋值 二.视频教程 一.结构体变量直接赋值 通过上节课的学习得出了一个结论:俩个相同类型的结构体变量直接可以只用赋值号进行赋值。 像这样: struct test {int a;int b; };int main(void) {struct test x {1,2};struct test …

反序列化靶机实战serial(保姆级教程)

一.信息收集 靶机地址下载:https://download.vulnhub.com/serial/serial.zip 打开靶机,在kali虚拟机中进行主机存活探测 可以知道靶机ip地址为192.168.133.171 然后扫描端口 可以发现有一个22端口跟80端口 然后接下来用kali扫描它的目录 可以发现有一…

10年仓库管理经验:“管、存、发、盘”一文搞定!

前段时间去一家仓储设备公司交流学习,和一位有着10年经验的老仓管聊了个痛快,从他那儿学到了不少仓库管理的实践方法。 回来自己整理了一套仓库管理高效的实用方法,现在就来跟大家伙儿聊聊仓库管理中那些常见问题,以及我是怎么琢…