如何让Python与Matlab生成完全一致的图像?
问题:Matlab与Python图像显示不一致(矩阵相同情况下)
问题描述
我在一个同时涉及Matlab和Python的项目中生成图像,尽管用于转换为图像的矩阵完全相同,但得到的图像却不一致。推测这与Python和Matlab的图像显示命令等效性有关,寻求解决方法。
MATLAB实现
代码
fmn0 = imread('cameraman.tif'); fmn=double(ifftshift(fmn0,2)); Fun=fftshift(fft(fmn,[],2),2); imshow(real(Fun))
输出图像

Python实现
代码
import numpy as np import matplotlib.pyplot as plt import cv2 def row_wise_fft(A): A = np.asarray(A) rowWiseFFT = np.zeros((A.shape[0], A.shape[1]), dtype='complex') for i in range(0, A.shape[0]): rowWiseFFT[i, :] = np.fft.fft(A[i,:]) return rowWiseFFT def row_wise_ifftshift(A): for i in range(0, len(A)): A[i] = np.fft.ifftshift(A[i]) return A def row_wise_fftshift(A): for i in range(0, len(A)): A[i] = np.fft.fftshift(A[i]) return A fmn = cv2.imread("cameraman.tif", cv2.IMREAD_GRAYSCALE) fun = row_wise_fftshift(row_wise_fft(row_wise_ifftshift(fmn))) plt.set_cmap("Greys_r") plt.imshow(fun.real)
输出图像

解决方案
既然矩阵完全一致,问题出在Matlab和Matplotlib的图像显示逻辑差异上:
- Matlab的
imshow默认会自动将数据的最小值映射到黑色,最大值映射到白色,自动适配数据的动态范围; - 而Matplotlib的
imshow对于浮点数类型的数据,默认会假设数据范围是[0,1],超出部分会被截断,这导致了显示对比度的差异。
修改Python代码中的imshow调用,让它和Matlab的行为对齐:
plt.set_cmap("Greys_r") # 手动设置显示范围为矩阵的最小和最大值,匹配Matlab imshow的自动缩放逻辑 plt.imshow(fun.real, vmin=np.min(fun.real), vmax=np.max(fun.real)) # 去掉坐标轴,更贴近Matlab输出效果 plt.axis('off') # 显示图像 plt.show()
另外可以优化行处理函数,用numpy的向量化操作替代循环,提升效率:
# 替换三个行处理函数,用numpy的轴参数直接实现 def row_wise_fft(A): return np.fft.fft(A, axis=1) def row_wise_ifftshift(A): return np.fft.ifftshift(A, axes=1) def row_wise_fftshift(A): return np.fft.fftshift(A, axes=1)
这样修改后,Python的输出图像就会和Matlab完全一致。
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

