PIL调整图像后保存再读取得到的numpy数组与直接生成的数组为何存在差异?
问题解答
数组a和b存在数值差异的原因
JPG属于有损压缩格式,调用save()方法将图像保存为JPG文件时,JPEG编码器会自动执行不可逆的压缩逻辑:丢弃部分人眼不敏感的像素信息以缩小文件体积,这个过程会直接改变原始像素的数值。
你得到的数组a是内存中resize后的图像直接转换的原始无损像素值,数组b是JPG压缩后重新解码得到的像素值,二者自然会存在差异。
调用.save()方法是否会修改原图像对应的numpy数组?
不会。save()仅会将内存中PIL图像对象的当前像素数据编码后写入磁盘,不会修改内存里的图像对象本身的像素值。你可以在save执行后再次将原image对象转换为numpy数组,和a对比会发现二者完全一致。
验证代码示例
resp = s3.get_object(Bucket=event['bucket'], Key=event['image_keys'][0]) data = resp['Body'] image_as_bytes = io.BytesIO(data.read()) image = Image.open(image_as_bytes).convert('RGB').resize((299, 299),Image.NEAREST) a = np.asarray(image) image.save('IMAGE_58990004_110132026B_13d64039_resized_lambda.jpg') b = np.asarray(Image.open('IMAGE_58990004_110132026B_13d64039_resized_lambda.jpg')) # 新增验证代码 c = np.asarray(image) print(np.array_equal(a, c)) # 输出True,证明save未修改原图像数据 print(np.array_equal(a, b)) # 输出False,证明差异来自JPG压缩
避免差异的方案
如果需要保存后读取的数组和原始数组完全一致,可以选择无损存储方案:
- 保存为PNG、BMP等无损压缩图像格式
- 直接调用
np.save()将数组存为.npy格式文件,读取时用np.load()即可得到完全一致的数组
内容的提问来源于stack exchange,提问作者Hamid K
相关产品推荐
相关产品推荐

