基于cv2、numpy→python实现二维DCT、IDCT变换

本文介绍了如何使用cv2和numpy库在Python中实现二维离散余弦变换(DCT)和逆离散余弦变换(IDCT)。通过电平偏移、数据类型转换、量化及反量化步骤,完成图像处理,同时计算了归一化均方误差(NMSE)来评估结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于cv2、numpy→python实现二维DCT、IDCT变换

原理见博客

以下实现python程序

导入所需库

# 江南大学物联18级——MH
import numpy as np
import cv2
import math

输入矩阵,arr存储8×8源图像数据,arr_brightness为亮度量化表数据

arr = np.array(([142, 144, 151, 156, 156, 157, 156, 156],
                [140, 143, 148, 150, 154, 155, 156, 155],
                [148, 150, 156, 160, 158, 158, 156, 158],
                [159, 160, 162, 161, 160, 159, 158, 160],
                [158, 162, 161, 164, 162, 160, 160, 162],
                [160, 164, 143, 162, 16
### Python 基于 DCT 的图像隐写术实现 #### 1. 离散余弦变换 (DCT) 的基本概念 离散余弦变换(Discrete Cosine Transform,简称 DCT)是一种常见的信号处理技术,能够将图像从空间域转换到频率域。这种变换的核心在于分离出图像的重要低频信息和次要高频信息[^4]。 对于基于 DCT 的图像隐写术而言,核心思想是通过对图像的 DCT 系数进行微调,在不影响视觉质量的前提下嵌入秘密信息。通常情况下,中频区域被认为是最佳的选择,因为它能够在透明性和鲁棒性之间取得平衡[^2]。 --- #### 2. 所需库及其功能说明 为了实现基于 DCT 的图像隐写术,需要用到以下几个主要库: - **OpenCV**: 提供了高效的图像读取、显示以及预处理能力。 - **NumPy**: 支持大规模数组操作和数值计算。 - **SciPy.fftpack**: 提供了快速傅里叶变换和离散余弦变换的功能。 具体导入方式如下所示: ```python import cv2 import numpy as np from scipy.fftpack import dct, idct ``` 这些工具的作用分别包括: - `cv2`: 负责加载并保存图像文件。 - `numpy`: 处理图像矩阵运算。 - `dct`/`idct`: 对图像块执行前向和反向离散余弦变换。 --- #### 3. 实现流程解析 ##### (1)图像准备阶段 在实际编码过程中,需要先将以灰度模式加载的图像转化为浮点型数据结构以便后续计算。这是因为 DCT 函数仅支持浮点类型的输入数据。 代码示例如下: ```python img = cv2.imread('image_path.jpg', cv2.IMREAD_GRAYSCALE) if img is None: raise ValueError("Image not found or path incorrect.") # 将图像转换为 float 类型 img_float = img.astype(np.float32) ``` 此处注意,如果未指定正确的路径或者图像损坏,则可能导致程序异常终止[^1]。 --- ##### (2)分块与 DCT 计算 由于标准 JPEG 编码采用的是8×8大小的小方格作为基础单元来进行量化处理,因此我们同样按照此规格划分整个画面,并逐一对每一块实施离散余弦变换(DCT)。 下面展示了一个简单的循环逻辑用于完成上述任务: ```python block_size = 8 height, width = img.shape[:2] # 初始化一个新的空白画布用来存储经过修改后的子区块 modified_img_blocks = [] for y in range(0, height, block_size): row_blocks = [] for x in range(0, width, block_size): # 截取出当前待处理的小矩形范围 sub_block = img_float[y:y+block_size, x:x+block_size] # 应用 DCT 变换至局部片段上 transformed_sub_block = dct(dct(sub_block.T).T) # 存储已变换的结果 row_blocks.append(transformed_sub_block) modified_img_blocks.append(row_blocks) ``` 这里强调一点:每次只针对单个小窗口单独做一次完整的二维DCT操作;最终会得到一系列由不同频率成分构成的新阵列集合。 --- ##### (3)嵌入秘密消息 假设现在有一串二进制形式表示的消息序列等待被植入原图之中。那么可以通过调整某些特定位置上的DCT系数值来达到这一目的——比如选取那些位于中间频带附近的项目最为合适。 举个例子来说吧,假如我们的目标是要把字符 'A'(ASCII码等于65即'01000001')藏进去的话,就可以依次改变相应索引处的数据项直至满足条件为止: ```python def embed_message(blocks, message_bits): index = 0 for i in range(len(blocks)): for j in range(len(blocks[i])): if index >= len(message_bits): break # 修改选定的位置 blocks[i][j][int(block_size / 2), int(block_size / 2)] += (-1)**message_bits[index]*0.1 index += 1 if index >= len(message_bits): break ``` 以上函数接受两个参数分别是之前生成好的所有分割出来的子区列表还有想要传递出去的实际位流内容。每当遇到符合条件的地方就适当增减其幅度从而间接记录下一个比特的状态信息[^3]。 --- ##### (4)恢复原始图像 当完成了全部必要的更改之后还需要再经历一轮逆方向的过程才能重新构建起可视化的版本出来给用户查看效果如何。这一步骤涉及到再次遍历每一个独立的部分并且运用IDCT指令还原回去原来的像素级表达样式。 下面是对应的伪代码框架示意: ```python reconstructed_image = np.zeros_like(img_float) for y in range(0, height, block_size): for x in range(0, width, block_size): current_block_index_y = y // block_size current_block_index_x = x // block_size inverse_transformed_block = idct(idct(modified_img_blocks[current_block_index_y][current_block_index_x].T).T) reconstructed_image[y:y+block_size, x:x+block_size] = inverse_transformed_block.clip(0, 255) final_output = reconstructed_image.astype(np.uint8) cv2.imwrite('output_with_hidden_data.png', final_output) ``` 最后记得一定要限定好数字区间以免超出正常界限造成溢出现象发生影响整体观感品质哦! --- ### 性能考量与抗攻击测试 尽管这种方法具备一定的隐蔽特性,但在面对诸如压缩、滤波等常见威胁时仍可能存在暴露风险。为此建议定期检验所选方案能否有效抵御各类潜在挑战因素的影响程度。例如可通过引入多种不同的干扰源组合模拟真实环境下的复杂状况进而全面评估系统的稳定可靠性水平[^5]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值