You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python将64×64灰度图压缩为指定40×40尺寸(无需存文件)

解决方案:内存中实现指定维度的高质量图像压缩

先明确你的核心需求:无需写入文件,直接在内存中将64×64灰度图转换为40×40的高质量数组。根据你提到的痛点,我分两种核心场景给出针对性方案:


场景1:直接得到40×40尺寸的高质量缩小图像

如果你只是需要把图像尺寸从64×64缩小到40×40(降采样),那么专业的图像插值方法比直接用DCT截断靠谱得多,全程在内存中操作,无需存文件:

用OpenCV实现(推荐)
import cv2
import numpy as np

# 假设你的64x64灰度图是numpy数组(dtype为uint8或float32)
img_64 = np.random.randint(0, 256, (64, 64), dtype=np.uint8)

# 用双三次插值缩小到40x40,这是视觉质量最优的降采样方法之一
img_40 = cv2.resize(img_64, (40, 40), interpolation=cv2.INTER_CUBIC)

# img_40就是你要的40x40数组,直接存在内存中
用PIL/Pillow实现
from PIL import Image
import numpy as np

img_64 = np.random.randint(0, 256, (64, 64), dtype=np.uint8)
# 转成PIL图像对象
pil_img = Image.fromarray(img_64)
# 用LANCZOS插值(比双三次更适合照片类图像)缩小
pil_img_40 = pil_img.resize((40, 40), Image.Resampling.LANCZOS)
# 转回numpy数组
img_40 = np.array(pil_img_40)

这两种方法的插值算法都经过工业级优化,缩小后的图像细节保留远好于直接截断DCT系数的方式。


场景2:得到40×40的压缩表示(可恢复原尺寸高质量图像)

如果你的需求是生成一个40×40的压缩数组,后续可以通过逆变换还原出接近原64×64图像的质量,那可以改进DCT的使用方式:

from scipy.fftpack import dct, idct
import numpy as np

img_64 = np.random.randint(0, 256, (64, 64), dtype=np.float32) / 255.0

# 执行正交化2D DCT(保证变换的能量集中性)
dct_coeffs = dct(dct(img_64, axis=0, norm='ortho'), axis=1, norm='ortho')

# 保留前40x40的低频系数(这就是你的40x40压缩数组)
compressed_coeffs = dct_coeffs[:40, :40]

# 恢复原图像时,补零回到64x64系数矩阵
restored_coeffs = np.zeros_like(dct_coeffs)
restored_coeffs[:40, :40] = compressed_coeffs

# 逆DCT还原图像
restored_img = idct(idct(restored_coeffs, axis=1, norm='ortho'), axis=0, norm='ortho')
restored_img = np.clip(restored_img * 255, 0, 255).astype(np.uint8)

这里用了norm='ortho'参数保证DCT的正交性,低频系数的能量集中性更好,还原后的图像质量会比你之前的尝试提升很多,全程在内存中完成。


额外需求:进一步压缩数组内存占用

如果得到40×40数组后,还想在内存中压缩它的字节大小(类似numpy.savez_compressed但不存文件),可以用zlib直接压缩数组的字节流:

import zlib
import numpy as np

# 假设已经得到40x40的数组img_40
img_bytes = img_40.tobytes()
# 内存中无损压缩(level=9为最高压缩比)
compressed_bytes = zlib.compress(img_bytes, level=9)

# 需要恢复时
decompressed_bytes = zlib.decompress(compressed_bytes)
restored_img_40 = np.frombuffer(decompressed_bytes, dtype=img_40.dtype).reshape(40, 40)

这种方式是无损压缩,恢复后的数组和原40×40数组完全一致,且无需写入任何文件。

内容的提问来源于stack exchange,提问作者Ramy Maher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:13:09