Python中离散小波变换与逆变换TypeError问题及语法咨询
解决DWT图像处理中的TypeError及语法验证问题
首先,我们先解决你遇到的TypeError:
1. 核心错误原因:numpy数组不能被“调用”
报错行if (file_name1(kk) == 0):里的file_name1是一个numpy数组(你通过im2double(messagee)得到的灰度图数组),而括号()是用来调用函数的语法,数组要访问元素必须用方括号[]索引。
因为你的file_name1是二维数组(灰度图的形状是[高度, 宽度]),直接用file_name1[kk]会取第kk行,而你需要的是遍历所有像素的一维序列,所以可以先把数组展平成一维,或者用flat属性访问:
# 替换原来的判断行 if file_name1.flat[kk] == 0:
或者提前把file_name1展平:
file_name1_flat = file_name1.flatten() # 然后循环里用 if file_name1_flat[kk] == 0:
2. DWT与IDWT的语法验证与修正
你的DWT/IDWT调用存在几个需要修正的地方:
(1)DWT输入需为单通道图像
你当前用dwt2(img, 'haar'),但img是cv2读取的彩色图(默认BGR三通道),dwt2适合处理单通道灰度图。你需要先把原图转成灰度:
# 替换原来的img读取行 img = cv2.imread('xyy.png', cv2.IMREAD_GRAYSCALE)
或者如果要处理彩色图,需要分三个通道分别做DWT/IDWT。
(2)IDWT的调用语法错误
idwt2的正确参数格式是:第一个参数是元组(cA, (cH, cV, cD)),第二个是小波基名称,并且你需要接收它的返回值(重构后的图像)。你当前的写法idwt2(cA,cH,cV,cD,'haar')是错误的,而且不应该在循环里重复调用IDWT——应该等所有系数修改完成后,再一次性执行IDWT重构图像。
正确的IDWT调用示例:
# 所有系数修改完成后执行 reconstructed_img = idwt2((cA, (cH, cV, cD)), 'haar') # 如果你需要裁剪回原图像尺寸 reconstructed_img = reconstructed_img[:Mc, :Nc]
3. 其他代码问题优化
除了上述问题,还有几个小问题需要调整:
Mc=np.shape(cover_object)和Nc=np.shape(cover_object)完全重复,应该直接获取图像的宽高:Mc, Nc = cover_object.shape # 如果是灰度图 # 如果是彩色图则是 Mc, Nc, _ = cover_object.shape- 你的随机序列生成逻辑有问题:
random.randint(512/2,512/2)等价于random.randint(256,256),只会返回256,导致pn_sequence_h和pn_sequence_v固定为511。如果要生成随机PN序列,应该调整范围,比如:# 生成-1或1的随机值,或者其他范围的随机数 pn_sequence_h = random.choice([-1, 1]) pn_sequence_v = random.choice([-1, 1]) - 循环范围
range(1,leng)会跳过第一个元素(索引0),如果要遍历所有像素,应该从0开始:range(leng)
修改后的完整代码示例
import cv2 import numpy as np import pywt import random # 读取灰度原图 img = cv2.imread('xyy.png', cv2.IMREAD_GRAYSCALE) def im2double(im): min_val = np.min(im.ravel()) max_val = np.max(im.ravel()) out = (im.astype('float') - min_val) / (max_val - min_val) return out k = 2 cover_object = im2double(img) Mc, Nc = cover_object.shape # 获取原图尺寸 print(Mc, Nc) # 处理水印:转灰度并归一化 water = cv2.imread('1.png') gray_water = cv2.cvtColor(water, cv2.COLOR_BGR2GRAY) cv2.imwrite('grayim.png', gray_water) file_name1 = im2double(gray_water) file_name1_flat = file_name1.flatten() # 展平为一维数组 leng = len(file_name1_flat) # 生成密钥 np.random.seed(0) key = round(100 * np.random.rand(1)[0]) # 修正rand(1)返回的是数组,取第一个元素 print(key) # 执行DWT分解 cA, (cH, cV, cD) = pywt.dwt2(cover_object, 'haar') # 修改高频系数 for kk in range(leng): # 生成随机PN序列(示例用-1/1,可根据需求调整) pn_sequence_h = random.choice([-1, 1]) pn_sequence_v = random.choice([-1, 1]) if file_name1_flat[kk] == 0: cH += k * pn_sequence_h cV += k * pn_sequence_v # 执行IDWT重构图像 reconstructed_img = pywt.idwt2((cA, (cH, cV, cD)), 'haar') # 裁剪回原图像尺寸 reconstructed_img = reconstructed_img[:Mc, :Nc] # 可选:保存重构后的图像 cv2.imwrite('watermarked_img.png', (reconstructed_img * 255).astype(np.uint8))
内容的提问来源于stack exchange,提问作者Shaan
相关产品推荐
相关产品推荐

