matplotlib保存imshow可视化图像时如何保持与原数组相同分辨率?
解决方案
问题原因
- 未主动控制matplotlib画布尺寸与dpi的对应关系,默认画布尺寸远大于数组对应像素大小
bbox_inches='tight'参数会自动裁剪画布边界,打乱预设尺寸比例,即便设置dpi=1也无法得到对应尺寸
方案1:精准控制matplotlib画布参数
通过显式指定画布尺寸、dpi,完全移除边距并关闭自动裁剪功能,即可得到和数组尺寸一致的图片:
import cv2 import numpy as np import matplotlib.pyplot as plt data = np.array([ [1,2,0,1], [0,1,2,1], [0,0,2,1] ]) height, width = data.shape # 画布尺寸单位为英寸,设置为(宽, 高),和数组的列数、行数一一对应 fig = plt.figure(figsize=(width, height), dpi=1) # 完全移除子图边距,让绘图区域占满整个画布 ax = fig.add_axes([0, 0, 1, 1]) ax.imshow(data) ax.axis('off') # 禁止添加自动裁剪参数bbox_inches='tight' fig.savefig("test.png", pad_inches=0) img = cv2.imread('test.png') print(img.shape) # 输出为 (3, 4, 3)
方案2:直接生成像素映射图片(更推荐)
跳过matplotlib的画布渲染逻辑,直接将数组数值映射为RGB像素后保存,100%匹配原始数组尺寸,稳定性更高:
import cv2 import numpy as np import matplotlib.cm as cm data = np.array([ [1,2,0,1], [0,1,2,1], [0,0,2,1] ]) # 使用和imshow默认一致的viridis colormap,可根据需求替换 cmap = cm.get_cmap('viridis') # 数值归一化后映射为RGBA颜色 norm_data = (data - data.min()) / (data.max() - data.min()) rgba_img = cmap(norm_data) # 转成opencv兼容的BGR格式,数值范围转为0-255 rgb_img = (rgba_img[...,:3] * 255).astype(np.uint8) bgr_img = cv2.cvtColor(rgb_img, cv2.COLOR_RGB2BGR) cv2.imwrite('test.png', bgr_img) img = cv2.imread('test.png') print(img.shape) # 输出为 (3, 4, 3)
内容的提问来源于stack exchange,提问作者voldr
相关产品推荐
相关产品推荐

