16×16图像2D离散傅里叶变换(DFT)实现出错,请求排查错误原因
问题背景与需求
我此前从事音频采样工作,现转向图像处理领域,正尝试为16×16尺寸的图像实现离散傅里叶变换(DFT)。我自制了图像解码器,图像文件中的每个像素以括号包裹的RGB值形式存储,例如纯红色像素表示为(255,0,0),每行包含16个像素,共16行。我处理的目标图像是粉红到红色的渐变图像,其编码格式如下:
(255,0,239)(255,0,223)(255,0,207)(255,0,191)(255,0,175)(255,0,159)(255,0,143)(255,0,127)(255,0,111)(255,0,95)(255,0,79)(255,0,63)(255,0,47)(255,0,31)(255,0,15)(255,0,0) (255,0,223)(255,0,210)(255,0,197)(255,0,184)(255,0,171)(255,0,158)(255,0,145)(255,0,132)(255,0,119)(255,0,106)(255,0,93)(255,0,80)(255,0,67)(255,0,54)(255,0,41)(255,0,15) (255,0,207)(255,0,196)(255,0,185)(255,0,174)(255,0,163)(255,0,152)(255,0,141)(255,0,130)(255,0,119)(255,0,108)(255,0,97)(255,0,86)(255,0,75)(255,0,64)(255,0,53)(255,0,31) (255,0,191)(255,0,182)(255,0,173)(255,0,164)(255,0,155)(255,0,146)(255,0,137)(250,0,121)(250,0,112)(250,0,103)(250,0,94)(250,0,85)(250,0,76)(255,0,67)(255,0,58)(255,0,47) (255,0,175)(255,0,168)(255,0,161)(255,0,154)(255,0,147)(255,0,140)(255,0,133)(255,0,126)(255,0,119)(255,0,112)(255,0,105)(255,0,98)(255,0,91)(255,0,84)(255,0,77)(255,0,63) (255,0,159)(255,0,154)(255,0,149)(255,0,144)(255,0,139)(255,0,134)(255,0,129)(255,0,124)(255,0,119)(255,0,114)(255,0,109)(255,0,104)(255,0,99)(255,0,94)(255,0,89)(255,0,79) (255,0,143)(255,0,140)(255,0,137)(255,0,134)(255,0,131)(255,0,128)(255,0,125)(255,0,122)(255,0,119)(255,0,116)(255,0,113)(255,0,110)(255,0,107)(255,0,104)(255,0,101)(255,0,95) (255,0,127)(255,0,126)(255,0,125)(255,0,124)(255,0,123)(255,0,122)(255,0,121)(255,0,120)(255,0,119)(255,0,118)(255,0,117)(255,0,116)(255,0,115)(255,0,114)(255,0,113)(255,0,111) (255,0,111)(255,0,113)(255,0,114)(255,0,115)(255,0,116)(255,0,117)(255,0,118)(255,0,119)(255,0,120)(255,0,121)(255,0,122)(255,0,123)(255,0,124)(255,0,125)(255,0,126)(255,0,127) (255,0,95)(255,0,101)(255,0,104)(255,0,107)(255,0,110)(255,0,113)(255,0,116)(255,0,119)(255,0,122)(255,0,125)(255,0,128)(255,0,131)(255,0,134)(255,0,137)(255,0,140)(255,0,143) (255,0,79)(255,0,89)(255,0,94)(255,0,99)(255,0,104)(255,0,109)(255,0,114)(255,0,119)(255,0,124)(255,0,129)(255,0,134)(255,0,139)(255,0,144)(255,0,149)(255,0,154)(255,0,159) (255,0,63)(255,0,77)(255,0,84)(255,0,91)(255,0,98)(255,0,105)(255,0,112)(255,0,119)(255,0,126)(255,0,133)(255,0,140)(255,0,147)(255,0,154)(255,0,161)(255,0,168)(255,0,175) (255,0,47)(255,0,58)(255,0,67)(255,0,76)(255,0,85)(255,0,94)(255,0,103)(250,0,112)(250,0,121)(255,0,137)(255,0,146)(255,0,155)(255,0,164)(255,0,173)(255,0,182)(255,0,191) (255,0,31)(255,0,53)(255,0,64)(255,0,75)(255,0,86)(255,0,97)(255,0,108)(255,0,119)(255,0,130)(255,0,141)(255,0,152)(255,0,163)(255,0,174)(255,0,185)(255,0,196)(255,0,207) (255,0,15)(255,0,41)(255,0,54)(255,0,67)(255,0,80)(255,0,93)(255,0,106)(255,0,119)(255,0,132)(255,0,145)(255,0,158)(255,0,171)(255,0,184)(255,0,197)(255,0,210)(255,0,223) (255,0,0)(255,0,15)(255,0,31)(255,0,47)(255,0,63)(255,0,79)(255,0,95)(255,0,111)(255,0,127)(255,0,143)(255,0,159)(255,0,175)(255,0,191)(255,0,207)(255,0,223)(255,0,239)
对2D DFT的理解与代码问题
我希望将该图像转换到离散频域(DFT)。1D DFT公式为:X[k] = Σ_{n=0}^{N-1} x[n] * exp(-j * 2 * π * k * n / N)。对于图像处理中的2D DFT,我的理解是先对每行进行DFT,再对每列进行DFT,然后将结果相加,例如第1行DFT结果为1,第1列DFT结果为2,则2D DFT中(1,1)位置的值为1+2(假设从第0行第0列开始计数)。我编写了如下Python代码,但实现结果出错,请求帮助排查错误所在:
import cmath filename = input("Enter a filename:\n") file = open(filename,'r') redArray = [] greenArray = [] blueArray = [] redArrayFourier = [] greenArrayFourier = [] blueArrayFourier = [] fourierRowsRed = [] fourierColumnsRed = [] fourierRowsBlue = [] fourierColumnsBlue = [] fourierRowsGreen = [] fourierColumnsGreen = [] rows, cols = 16, 16 for _ in range(rows): row = [] for _ in range(cols): row.append(0) redArray.append(row) for _ in range(rows): row = [] for _ in range(cols): row.append(0) blueArray.append(row) for _ in range(rows): row = [] for _ in range(cols): row.append(0) greenArray.append(row) for _ in range(rows): row = [] for _ in range(cols): row.append(0) redArrayFourier.append(row) for _ in range(rows): row = [] for _ in range(cols): row.append(0) blueArrayFourier.append(row) for _ in range(rows): row = [] for _ in range(cols): row.append(0) greenArrayFourier.append(row) for i in range(rows): fourierRowsRed.append(0) for i in range(rows): fourierRowsBlue.append(0) for i in range(rows): fourierRowsGreen.append(0) for i in range(cols): fourierColumnsRed.append(0) for i in range(cols): fourier...
错误排查与修正方案
首先得说,你对2D DFT的理解有个核心误区:2D DFT绝对不是行DFT结果加列DFT结果!正确的流程是:
- 先对图像的每一行单独做1D DFT,得到一个中间结果矩阵
- 再对这个中间矩阵的每一列单独做1D DFT,最终得到的就是完整的2D DFT结果
(反过来先做列DFT再做行DFT,结果是完全一致的,但顺序不影响,核心是两次一维变换的级联,不是相加)
再看代码里的具体问题:
1. 图像读取解析逻辑完全缺失
代码只打开了文件,但没有读取任何内容,也没有解析像素的逻辑——redArray、greenArray、blueArray始终是全0矩阵,后续计算自然全错。你需要用正则表达式提取每行的RGB值,示例代码:
import re # 改用with语句自动管理文件,避免资源泄漏 with open(filename, 'r') as file: content = file.read().splitlines() for i, line in enumerate(content): # 提取所有括号内的RGB数值对 pixels = re.findall(r'\((\d+),(\d+),(\d+)\)', line) for j, (r, g, b) in enumerate(pixels): redArray[i][j] = int(r) greenArray[i][j] = int(g) blueArray[i][j] = int(b)
2. DFT计算逻辑完全缺失
代码只初始化了一堆数组,但没有实现行DFT和列DFT的计算逻辑。先写一个通用的1D DFT函数,再分别处理行和列:
def dft_1d(signal): N = len(signal) result = [0 + 0j] * N for k in range(N): for n in range(N): result[k] += signal[n] * cmath.exp(-1j * 2 * cmath.pi * k * n / N) return result # 第一步:对每行做DFT for i in range(rows): red_row_dft = dft_1d(redArray[i]) green_row_dft = dft_1d(greenArray[i]) blue_row_dft = dft_1d(blueArray[i]) for j in range(cols): redArrayFourier[i][j] = red_row_dft[j] greenArrayFourier[i][j] = green_row_dft[j] blueArrayFourier[i][j] = blue_row_dft[j] # 第二步:对每列做DFT for j in range(cols): # 提取当前列的所有元素 red_col = [redArrayFourier[i][j] for i in range(rows)] green_col = [greenArrayFourier[i][j] for i in range(rows)] blue_col = [blueArrayFourier[i][j] for i in range(rows)] # 计算列DFT red_col_dft = dft_1d(red_col) green_col_dft = dft_1d(green_col) blue_col_dft = dft_1d(blue_col) # 将结果写回傅里叶矩阵 for i in range(rows): redArrayFourier[i][j] = red_col_dft[i] greenArrayFourier[i][j] = green_col_dft[i] blueArrayFourier[i][j] = blue_col_dft[i]
3. 冗余变量过多
代码里的fourierRowsRed、fourierColumnsRed
相关产品推荐
相关产品推荐

