数字水印 | 离散余弦变换 DCT 基本原理及 Python 代码实现

news2024/9/8 12:20:07

目录

      • 1 基本原理
      • 2 代码实现
      • 3 图像压缩



1 基本原理

参考博客:https://www.cnblogs.com/zxporz/p/16072580.html

D C T \mathsf{DCT} DCT 全称为 D i s c r e t e   C o s i n e   T r a n s f o r m \mathsf{Discrete\ Cosine\ Transform} Discrete Cosine Transform,即离散余弦变换。 D C T \mathsf{DCT} DCT 变换属于傅里叶变换的一种,常用于对信号和图像(包括图片和视频)进行数据压缩。 D C T \mathsf{DCT} DCT 是视频压缩史上最重要的发明之一,对于 H . 26 X \mathsf{H.26X} H.26X J P E G \mathsf{JPEG} JPEG 等压缩标准的制定至关重要。

虽然 D C T \mathsf{DCT} DCT 具有比较复杂的数学公式,但是我们这里仅做简单理解。

对一幅图像执行离散余弦变换 ( D C T ) \mathsf{(DCT)} (DCT) 相当于将图像的能量集中在变换系数的左上角,这部分系数被称为直流 ( D C ) \mathsf{(DC)} (DC) 系数。直流系数是 D C T \mathsf{DCT} DCT 最重要的输出之一,因为它携带了原始图像的大部分信息。其余的系数,分布在左上角之外的区域,被称为交流 ( A C ) \mathsf{(AC)} (AC) 系数。这些系数包含了图像的细节信息,反映了图像的纹理和边缘。

只要对这些 D C T \mathsf{DCT} DCT 系数做逆离散余弦变换 ( I D C T ) \mathsf{(IDCT)} (IDCT),理论上就可以重建出原始图像的像素矩阵。需要注意的是, D C T \mathsf{DCT} DCT 本身并不直接压缩数据。它起到的是一个准备作用,为后续的量化、编码等压缩步骤提供了有力的数学基础。量化过程会根据需要压缩的强度,减少 A C \mathsf{AC} AC 系数中的某些值,从而实现数据压缩。

假设一张图片由 3 × 3 3\times3 3×3 个像素块构成,如下图所示:

原文说的是,取一个图像中的一部分,且这个部分只包含 3 × 3 3\times3 3×3 个像素。

如上图所示,相当于是把其余格的部分信息(特征)都抽取到了第一个格。第一个格的像素值就是这个图像的低频信息,其余格的就是这个图像的高频信息。低频信息主要表示的是一张图的总体样貌,一般低频系数的值也比较大。而高频信息主要表示的是图像中人物或物体的细节,一般高频系数的数量较多。做完 D C T \mathsf{DCT} DCT 变换后,低频信息和高频信息就分离开来了。



2 代码实现

参考博客:https://blog.csdn.net/qq_41821067/article/details/114113677

import cv2
import numpy as np
from matplotlib import pyplot as plt


# 处理原始图像
img = cv2.imread('logo.jpg', 0)  # 读取图像为灰度图像
print("img.shape:", img.shape)
img1 = img.astype('float32')  # 将unit8类型转换为float类型

# 进行离散余弦变换
img_dct = cv2.dct(img1)
print("img_dct:", img_dct)
print("img_dct.shape:", img_dct.shape)

# 进行对数处理
img_dct_log = np.log(abs(img_dct))
print("img_dct_log:", img_dct_log)

# 进行逆离散余弦变换
img_recor = cv2.idct(img_dct)
print("img_recor:", img_recor)
print("img_recor.shape:", img_recor.shape)

# 判断是否相同
print("img:", img)
print("img_recor:", img_recor)
print(abs(img - img_recor) < 1)

# 画图
plt.subplot(1, 4, 1)
plt.title("Original Image", fontsize=12, loc="center")
plt.axis('off')
plt.imshow(img, cmap="gray")

plt.subplot(1, 4, 2)
plt.title("Coefficients", fontsize=12, loc="center")
plt.axis('off')
plt.imshow(img_dct, cmap="gray")

plt.subplot(1, 4, 3)
plt.title("Log", fontsize=12, loc="center")
plt.axis('off')
plt.imshow(img_dct_log, cmap="gray")

plt.subplot(1, 4, 4)
plt.title("Recovered Image", fontsize=12, loc="center")
plt.axis('off')
plt.imshow(img_recor, cmap="gray")

plt.savefig('test.jpg', dpi=400, bbox_inches='tight')
plt.show()

代码说明:

  • 根据 img.shapeimg_dct.shape 的结果可知 D C T \mathsf{DCT} DCT 并不会改变图像的大小。
  • 根据 img_dct 可知 D C T \mathsf{DCT} DCT 系数非常小,以至于在视觉上难以区分。为了更好地可视化这些系数,我们对其进行对数变换,以拉伸坐标轴的刻度,使得小的系数在图像中也能显示出来。
  • 根据 imgimg_recor 可知原始图像和还原后的图像并不完全相等,但是根据 print(abs(img - img_recor) < 1) 可知二者之间的像素差值不会超过 1 1 1

效果如下:

在这里插入图片描述



3 图像压缩

import cv2
from matplotlib import pyplot as plt


# 处理原始图像
img = cv2.imread('logo.jpg', 0)  # 读取图像为灰度图像
img1 = img.astype('float32')  # 将unit8类型转换为float类型

# 进行离散余弦变换
img_dct = cv2.dct(img1)

# 压缩图像
zip_len = [10, 20, 50, 100, 200, 300, 500, 800]  # 压缩后的图像大小

for i in range(len(zip_len)):
    # 进行逆离散余弦变换:仅保留左上角的部分数据
    img_recor = cv2.idct(img_dct[0:zip_len[i], 0:zip_len[i]])
    print("img_recor.shape:", img_recor.shape)

    # 画图
    plt.subplot(2, int(len(zip_len) / 2), i + 1)
    plt.title("zip_len={zip_len}".format(zip_len=zip_len[i]), fontsize=12, loc="center")
    plt.axis('off')
    plt.imshow(img_recor, cmap="gray")

plt.savefig('compress.jpg', dpi=400, bbox_inches='tight')
plt.show()

核心代码:

cv2.idct(img_dct[0:zip_len[i], 0:zip_len[i]])

使用 D C T \mathsf{DCT} DCT 进行图片压缩的本质,就是仅保留部分左上角的 D C T \mathsf{DCT} DCT 系数,通过逆变换构建被压缩了的图像。

效果如下:

在这里插入图片描述



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

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

相关文章

HTTPS证书——网站如何实现HTTPS访问?

实现网站HTTPS访问可以简化为以下四个基本步骤&#xff0c;确保过程既通俗易懂又条理清晰&#xff1a; 1. 申请SSL证书 - 目的&#xff1a;SSL证书是实现HTTPS加密的关键&#xff0c;它验证了网站的身份&#xff0c;并提供了加密数据所需的密钥。 - 操作&#xff1a;首先&…

面试手撕——使用两个线程交替打印1-100

记录一下使用两个线程交替打印1-100的操作: /*** description: 使用两个线程交替打印1-100* author: Jay* create: 2024-05-27 21:29**/ public class print_1_to_100 {static volatile int flag 1; //此处需要加关键字volatile保证变量之间的可见性&#xff0c;否则程序将会…

TS(TypeScript)中Array数组无法调出使用includes方法,显示红色警告

解决方法 打开tsconfig.json文件&#xff0c;添加"lib": ["es7", "dom"]即可。 如下图所示。

move base全解

0. 简介 之前我们专门有一节讲到了《move_base源码学习》。主要介绍了MoveBase基类中函数的大概意思以及调用的方式。move_base是ROS下关于机器人路径规划的中心枢纽。它通过订阅激光雷达、map地图、amcl的定位等数据&#xff0c;然后规划出全局和局部路径&#xff0c;再将路径…

数组-两个升序数组中位数

一、题目描述 二、解题思路 (一).基本思想&#xff1a; 如果列表总长度allsize( arr1.size()arr2.size() ) 为奇数时&#xff0c;中位数位置应该在两个列表排序后的第 allsize/2 位置处&#xff0c;如果allsize为偶数&#xff0c;中位数应该取 (allsize/2)-1 和 allsize/2 的…

python数据类型之列表

目录 1.创建列表 2.列表基础操作 常用操作 对列表元素顺序随机打乱 列表下标和切片 字符串分割为列表 列表位移 列表切片替换 3.列表内置方法 4.列表排序 简单排序 使用key参数按指定规则排序 二维列表排序 自定义排序规则函数 5.列表排序算法 选择排序 柱状图…

4-主窗口

4-主窗口 1、简介2 菜单栏、工具栏、状态栏2.1 菜单栏2.2 QAction2.3 工具栏2.4 状态栏 3 混合方式UI设计 1、简介 QMainWindow是一个为用户提供主窗口程序的类&#xff0c;包含一个菜单栏、多个工具栏、多个停靠控件、一个状态栏以及一个中心控件&#xff0c;是许多应用程序&…

宝塔部署前后端分离项目手册

文章目录 安装宝塔安装环境开始部署1. 前端Vue项目1.先本地启动前端项目&#xff08;记住端口号&#xff09;2.打包前端项目3.上传前端项目4.创建PHP站点5.安全里开放端口号6.测试前端 2. 后端boot项目1. 先在本地跑起来2.修改数据库的配置信息3. 项目打包4. nohup启动项目4.1 …

2024年必看!会声会影神器升级,让你的视频制作技能直线上升

在数字媒体内容呈现爆炸式增长的今天&#xff0c;无论是个人还是企业&#xff0c;都开始重视视频制作与编辑的质量。一款优秀的视频编辑软件&#xff0c;不仅需要具备强大的功能&#xff0c;更需要提供直观、高效的用户体验。在这样的背景下&#xff0c;会声会影2024应运而生&a…

《开发问题解决》Window下7z解压:cannot create symbolic link : 客户端没有所需的特权

问题描述&#xff1a; 今天使用7z来解压东西的是突然出现这个问题。 问题解决&#xff1a; download直接下载到c盘中&#xff0c;由于所在文件夹有权限限制。无法进行正常解压。 7.zip解压时使用管理员权限进行解压&#xff0c;解压时使用管理员权限。即如图 使用管理员权限重…

基于飞书机器人跨账号消息提醒

事情的起因是飞书中不同的账号不能同时登录&#xff0c;虽然可以在飞书的账号切换页面看到其他账号下是否有消息提醒&#xff08;小红点&#xff09;&#xff0c;但是无法实现提醒功能&#xff0c;很不优雅&#xff0c;因此本文尝试提出一种新的方式实现不同账号之间的提醒功能…

基于Go实现的分布式主键系统

基于Go实现的分布式主键系统 摘要 随着互联网的发展&#xff0c;微服务得到了快速的发展&#xff0c;在微服务架构下&#xff0c;分布式主键开始变得越来越重要。目前分布式主键的实现方式颇多&#xff0c;有基于数据库自增的、基于UUID的、基于Redis自增的、基于数据库号段的…

时空AI软件:地理信息与遥感领域的智慧引擎

在地理信息与遥感技术的广阔疆域&#xff0c;时空AI软件如同一颗璀璨新星&#xff0c;将时空信息与智能深度融合&#xff0c;驱动着地理信息分析、决策支持、环境监测、城市规划等领域的深刻变革。本文将深入剖析其技术核心、应用实例、未来趋势&#xff0c;探索时空AI软件如何…

OrangePi Kunpeng Pro 开发板测评及Python开发实测

一、背景 首先感谢 创新乐知通过CSDN 邀请本人&#xff0c;参与这次 评测活动。这块开发板是香橙派联合华为精心打造&#xff0c;具有超强算力的鲲鹏开发板。本人使用最多的还是树莓派系列的板子&#xff0c;国产板子特别是华为为核心的板子还是头一次使用&#xff0c;特别感兴…

使用 Spring Cloud Alibaba AI 构建 RAG 应用

作者&#xff1a;姬世文 背景介绍 RAG&#xff08;Retrieval Augmented Generation&#xff09; 检索增强生成&#xff08;RAG&#xff09;是一种用于将数据与人工智能模型集成的技术。在 RAG 工作流程中&#xff0c;第一步将文档数据加载到矢量数据库&#xff08;例如 Redi…

【Day8:JAVA字符串的学习】

目录 1、常用API2、String类2.1 String类的特点2.2 String类的常见构造方法2.3 String类的常见面试题&#xff1a;2.3.1 面试题一&#xff1a;2.3.2 面试题二&#xff1a;2.3.3 面试题三&#xff1a;2.3.4 面试题四&#xff1a; 2.4 String类字符串用于比较的方法2.5 String类字…

万博智云×华为云 | HyperBDR云容灾上架,开启联营联运新篇章

日前&#xff0c;万博智云HyperBDR云容灾正式入驻华为云云商店&#xff0c;成为华为云基础软件领域联营联运合作伙伴。通过联营联运&#xff0c;双方将进一步加深在产品、解决方案、渠道拓展等多方面的强强联合&#xff0c;为企业提供更加安全、高效的数据保护解决方案&#xf…

halcon 传统缺陷检测

一、电路检测 算子解释 dyn_threshold *dyn_threshold 利用局部阈值分割图像*OrigImage (input_object)&#xff1a;原始图像*ThresholdImage (input_object)&#xff1a;处理后图像&#xff08;一般采用滤波处理&#xff09;*RegionDynThresh (output_object)&#xff1…

GpuMall智算云:QwenLM/Qwen1.5/Qwen1.5-7B-Chat

Qwen 是阿里巴巴集团 Qwen 团队的大型语言模型和大型多模态模型系列&#xff0c;现在大型语言模型已经升级到 Qwen1.5 版本。 GpuMall智算云 | 省钱、好用、弹性。租GPU就上GpuMall,面向AI开发者的GPU云平台 无论是语言模型还是多模态模型&#xff0c;都在大规模的多语言和多模…

新楚文化知网收录文学艺术类期刊投稿

《新楚文化》是由国家新闻出版总署批准&#xff0c;湖北省文学艺术界联合会主管&#xff0c;湖北今古传奇传媒集团有限公司主办的正规期刊。主要刊登文化、文学、艺术类稿件&#xff1b;包括传统文化、非遗、历史文化、地方文化、中外友好文化交流、文学作品研究、艺术研究等方…