常见的JPEG 格式不支持存储 32 位浮点值。即使是某种常见的JPEG 2000 格式也无法做到这一点。您可能会看一下OpenEXR 格式,OpenCV 也支持这种格式,并且每个通道可以存储 32 位浮点值。不过,总体而言,OpenEXR 似乎不太受支持。
这是一些小例子,也与一些 JPEG 导出比较:
import cv2
from matplotlib import pyplot as plt
import numpy as np
# Generate image
x = np.linspace(0, 1, 1024, dtype=np.float32)
x, y = np.meshgrid(x, x)
img = np.stack([x, y, np.fliplr(x)], axis=2)
# Save image as JPG and EXR
cv2.imwrite('img.jpg', img * 255)
cv2.imwrite('img.exr', img)
# Read JPG and EXR images
jpg = cv2.imread('img.jpg', cv2.IMREAD_UNCHANGED)
exr = cv2.imread('img.exr', cv2.IMREAD_UNCHANGED)
# Compare original with EXR image
print('Original image shape and type: ', img.shape, img.dtype)
print('EXR image shape and type: ', exr.shape, exr.dtype)
print('Original image == EXR image:', np.all(img == exr))
# Original image shape and type: (1024, 1024, 3) float32
# EXR image shape and type: (1024, 1024, 3) float32
# Original image == EXR image: True
# Show all images
plt.figure(1, figsize=(18, 9))
plt.subplot(2, 3, 1), plt.imshow(img), plt.title('Original')
plt.subplot(2, 3, 2), plt.imshow(jpg), plt.title('JPG image')
plt.subplot(2, 3, 3), plt.imshow(exr), plt.title('EXR image')
plt.subplot(2, 3, 4), plt.imshow(img[200:300, 500:600, ...])
plt.subplot(2, 3, 5), plt.imshow(jpg[200:300, 500:600, ...])
plt.subplot(2, 3, 6), plt.imshow(exr[200:300, 500:600, ...])
plt.tight_layout(), plt.show()
剧情是这样的:
我不确定,在比较 JPEG 导出和 Matplotlib 图时,您看到了什么差异,但对于给定的示例,从我的角度来看,原始图像、JPG 图像和 EXR 图像之间的差异几乎没有见过。当然,你可以在缩放时看到 JPG 图片中的一些块,但这真的“伪造”了“图片”吗?
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.19041-SP0
Python: 3.9.1
PyCharm: 2021.1.1
Matplotlib: 3.4.1
NumPy: 1.20.2
OpenCV: 4.5.1
----------------------------------------