我正在测试如何将 8 位(0-255)数据表保存为图像格式以存储原始数据文件并加载图像以检索相同的数据。
下面的代码显示了我当前正在尝试的内容。具有 32x32 数据表 (random_data)。
我想将此数据以灰度形式绘制为 32x32 像素图像,然后打开/检索它以查看哪种图像格式最能保留该数据。如果可以做到这一点,我想将其缩放到更大尺寸的数据/图像。
以下是我面临的一些挑战:
问题1:
Plt.figure
和plt.savefig
没有直接选项来绘制 32x32 数据表并将其保存为 32x32 像素图像,我添加并手动调整了 dpi 设置和 Figsize 选项和参数以获得 32x32 像素。但是,当我打开保存的图像文件然后将其转换为数组时,它不会给出与输入相同的值。 (见下文)问题2:
是否可以将图形保存为 PNG 和 JPEG 之外的其他较新的图像格式? (例如 AVIF、WebP、HEIF、JPEG XL、JPEG XS 等)?问题3:
如果问题 2 无法实现,那么保存和保留相同数据值的最佳图像格式是什么?
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
from numpy import asarray
import sys
import numpy
numpy.set_printoptions(threshold=sys.maxsize)
# Randomly generated data table in 0-255
random_data=([179,22,29,72,118,117,88,182,155,114,95,62,75,67,30,252],
[161,88,76,74,70,99,136,246,178,113,233,125,177,135,94,72],
[46,123,106,28,192,240,85,164,75,183,160,126,157,140,182,98],
[6,147,229,193,224,103,31,133,19,176,194,171,223,123,173,204],
[228,25,207,39,93,119,34,157,150,186,161,242,2,89,187,226],
[109,198,151,25,122,136,48,250,245,102,205,180,74,229,243,27],
[135,116,223,40,233,243,95,126,54,153,246,57,120,162,8,143],
[78,249,58,237,80,237,99,92,67,157,64,200,0,249,31,33],
[154,111,170,120,143,81,97,237,249,85,154,135,41,163,147,8],
[137,195,189,167,196,240,185,117,199,179,57,170,87,253,89,152],
[183,250,88,189,143,232,4,213,110,254,246,240,100,103,99,229],
[155,205,45,236,60,87,121,216,99,3,243,61,107,104,180,58],
[240,52,238,143,99,51,230,139,49,3,175,70,160,226,85,108],
[98,131,157,38,120,4,9,87,122,179,118,41,79,120,119,246],
[120,131,21,48,225,191,149,144,133,46,56,170,225,207,45,139],
[118,59,128,238,228,110,70,247,132,225,223,77,53,161,115,197])
# Trying to plot the data in 32x32 pixel image then saving it
plt.figure(figsize=(.32, .32), dpi=100, frameon=False)
plt.imshow(random_data, interpolation='none', vmin=0, vmax=255, cmap='gray')
plt.axis('off')
plt.savefig('test.png', dpi=133, bbox_inches='tight', pad_inches=0)
# Calling saved image then converting it to array to compare it against the original input data
test_output=Image.open('test.png')
test_output_gray=test_output.convert('L')
test_output_gray=asarray(test_output_gray)
print(test_output_gray.shape)
print(test_output_gray)
输出如下:
[[179 179 22 22 29 29 72 72 118 118 117 117 88 88 182 182 155 155
155 113 113 95 95 62 62 75 75 67 67 30 30 252]
[161 161 88 88 76 76 73 73 70 70 99 99 136 136 246 246 178 178
178 113 113 233 233 125 125 177 177 135 135 94 94 72]
[161 161 88 88 76 76 73 73 70 70 99 99 136 136 246 246 178 178
178 113 113 233 233 125 125 177 177 135 135 94 94 72]
[ 46 46 123 123 105 105 28 28 192 192 240 240 85 85 163 163 75 75
75 183 183 160 160 126 126 157 157 140 140 182 182 97]
[ 46 46 123 123 105 105 28 28 192 192 240 240 85 85 163 163 75 75
75 183 183 160 160 126 126 157 157 140 140 182 182 97]
[ 6 6 147 147 229 229 193 193 224 224 103 103 31 31 133 133 19 19
19 176 176 194 194 171 171 223 223 123 123 173 173 204]
[ 6 6 147 147 229 229 193 193 224 224 103 103 31 31 133 133 19 19
19 176 176 194 194 171 171 223 223 123 123 173 173 204]
[227 227 25 25 207 207 39 39 93 93 119 119 34 34 157 157 150 150
150 186 186 161 161 242 242 2 2 89 89 187 187 226]
[227 227 25 25 207 207 39 39 93 93 119 119 34 34 157 157 150 150
150 186 186 161 161 242 242 2 2 89 89 187 187 226]
[109 109 198 198 151 151 25 25 121 121 136 136 48 48 250 250 245 245
245 102 102 205 205 179 179 73 73 229 229 243 243 27]
[109 109 198 198 151 151 25 25 121 121 136 136 48 48 250 250 245 245
245 102 102 205 205 179 179 73 73 229 229 243 243 27]
[135 135 116 116 223 223 40 40 233 233 243 243 95 95 126 126 54 54
54 153 153 246 246 56 56 120 120 162 162 8 8 143]
[135 135 116 116 223 223 40 40 233 233 243 243 95 95 126 126 54 54
54 153 153 246 246 56 56 120 120 162 162 8 8 143]
[ 78 78 249 249 58 58 237 237 80 80 237 237 99 99 92 92 67 67
67 157 157 64 64 200 200 0 0 249 249 31 31 32]
[ 78 78 249 249 58 58 237 237 80 80 237 237 99 99 92 92 67 67
67 157 157 64 64 200 200 0 0 249 249 31 31 32]
[154 154 111 111 170 170 120 120 143 143 81 81 97 97 237 237 249 249
249 85 85 154 154 135 135 40 40 163 163 147 147 8]
[154 154 111 111 170 170 120 120 143 143 81 81 97 97 237 237 249 249
249 85 85 154 154 135 135 40 40 163 163 147 147 8]
[154 154 111 111 170 170 120 120 143 143 81 81 97 97 237 237 249 249
249 85 85 154 154 135 135 40 40 163 163 147 147 8]
[137 137 195 195 189 189 167 167 195 195 240 240 185 185 117 117 199 199
199 179 179 56 56 170 170 87 87 253 253 89 89 152]
[137 137 195 195 189 189 167 167 195 195 240 240 185 185 117 117 199 199
199 179 179 56 56 170 170 87 87 253 253 89 89 152]
[183 183 250 250 88 88 189 189 143 143 232 232 4 4 213 213 110 110
110 254 254 246 246 240 240 100 100 103 103 99 99 229]
[183 183 250 250 88 88 189 189 143 143 232 232 4 4 213 213 110 110
110 254 254 246 246 240 240 100 100 103 103 99 99 229]
[155 155 205 205 44 44 236 236 60 60 87 87 121 121 216 216 99 99
99 3 3 243 243 60 60 107 107 104 104 179 179 58]
[155 155 205 205 44 44 236 236 60 60 87 87 121 121 216 216 99 99
99 3 3 243 243 60 60 107 107 104 104 179 179 58]
[240 240 52 52 238 238 143 143 99 99 51 51 230 230 139 139 48 48
48 3 3 175 175 70 70 160 160 226 226 85 85 108]
[240 240 52 52 238 238 143 143 99 99 51 51 230 230 139 139 48 48
48 3 3 175 175 70 70 160 160 226 226 85 85 108]
[ 97 97 131 131 157 157 38 38 120 120 4 4 9 9 87 87 121 121
121 179 179 118 118 40 40 79 79 120 120 119 119 246]
[ 97 97 131 131 157 157 38 38 120 120 4 4 9 9 87 87 121 121
121 179 179 118 118 40 40 79 79 120 120 119 119 246]
[120 120 131 131 21 21 48 48 225 225 191 191 149 149 144 144 133 133
133 46 46 56 56 170 170 225 225 207 207 44 44 139]
[120 120 131 131 21 21 48 48 225 225 191 191 149 149 144 144 133 133
133 46 46 56 56 170 170 225 225 207 207 44 44 139]
[118 118 59 59 128 128 238 238 227 227 110 110 70 70 247 247 131 131
131 225 225 223 223 77 77 52 52 161 161 115 115 197]
[118 118 59 59 128 128 238 238 227 227 110 110 70 70 247 247 131 131
131 225 225 223 223 77 77 52 52 161 161 115 115 197]]
谢谢。
最佳答案
我们必须保存图像,而不是保存图形。
由于图形经过调整显示,通常与原始图像有所不同。
在您的示例中,原始图像尺寸为 16x16,图形尺寸为 32x32,因此图像和图形必须不同。
注意:我们可能会显示调整大小的图像,而不调整源图像的大小(保持原始图像不变)。
使用 Pillow 将图像保存为 PNG 的示例:
将 random_data 从列表转换为
uint8
类型的 NumPy 数组。将 NumPy 数组转换为
Image
对象,并保存图像。random_data_arr = np.array(random_data, np.uint8) # Convert random_data to NumPy array of type 'uint8' pil_image = Image.fromarray(random_data_arr) # Convert the NumPy array to PIL image pil_image.save('test.png') # Save the image in PNG format
加载 PNG 图像并与 random_data_arr
进行比较的示例:
使用
Image.open('test.png')
打开图像。将图像对象转换为 NumPy 数组。
使用
np.array_equal
方法比较数组test_output = Image.open('test.png') test_output_gray = np.array(test_output) are_equal = np.array_equal(random_data_arr, test_output_gray) # True if random_data_arr and test_output_gray are equal print('are_equal = ' + str(are_equal)) # are_equal = True
问题2
安装合适的 Python 包后可以使用更新的图像格式。
可能存在限制 - 例如,WebP packge 不支持灰度图像,因此我们必须在保存之前将图像转换为 RGB,并在加载后转换回灰度图像。
使用 WebP 格式的示例:
安装WebP Python bindings包:pip install webp
。
使用WebP图像格式保存、加载和比较的示例:
webp.save_image(pil_image.convert('RGB'), 'test.webp', lossless=True)
webp_output = webp.load_image('test.webp') # Load test.webp to PIL image
webp_output_gray = np.array(webp_output.convert('L')) # Convert to grayscale and to NumPy array
are_webp_equal = np.array_equal(random_data_arr, webp_output_gray) # True if random_data_arr and webp_output_gray are equal
print('are_webp_equal = ' + str(are_webp_equal)) # are_webp_equal = True
问题3
最佳图像格式(就文件大小而言)是特定于域的 - 最佳格式取决于图像的内容。
使用有损图像压缩时,所选格式更相关。
当您的问题中使用无损图像压缩时,在大多数情况下,输出文件不会小很多(在大多数情况下不少于 PNG 文件的一半)。
注意:随机数据根本没有被很好地压缩。
完整代码示例:
#import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
import webp
#np.set_printoptions(threshold=sys.maxsize)
# Randomly generated data table in 0-255
random_data = ([179,22,29,72,118,117,88,182,155,114,95,62,75,67,30,252],
[161,88,76,74,70,99,136,246,178,113,233,125,177,135,94,72],
[46,123,106,28,192,240,85,164,75,183,160,126,157,140,182,98],
[6,147,229,193,224,103,31,133,19,176,194,171,223,123,173,204],
[228,25,207,39,93,119,34,157,150,186,161,242,2,89,187,226],
[109,198,151,25,122,136,48,250,245,102,205,180,74,229,243,27],
[135,116,223,40,233,243,95,126,54,153,246,57,120,162,8,143],
[78,249,58,237,80,237,99,92,67,157,64,200,0,249,31,33],
[154,111,170,120,143,81,97,237,249,85,154,135,41,163,147,8],
[137,195,189,167,196,240,185,117,199,179,57,170,87,253,89,152],
[183,250,88,189,143,232,4,213,110,254,246,240,100,103,99,229],
[155,205,45,236,60,87,121,216,99,3,243,61,107,104,180,58],
[240,52,238,143,99,51,230,139,49,3,175,70,160,226,85,108],
[98,131,157,38,120,4,9,87,122,179,118,41,79,120,119,246],
[120,131,21,48,225,191,149,144,133,46,56,170,225,207,45,139],
[118,59,128,238,228,110,70,247,132,225,223,77,53,161,115,197])
# Trying to plot the data in 32x32 pixel image then saving it
#plt.figure(figsize=(.32, .32), dpi=100, frameon=False)
#plt.imshow(random_data, interpolation='none', vmin=0, vmax=255, cmap='gray')
#plt.axis('off')
#plt.savefig('test.png', dpi=133, bbox_inches='tight', pad_inches=0)
random_data_arr = np.array(random_data, np.uint8) # Convert random_data to NumPy array of type 'uint8'
pil_image = Image.fromarray(random_data_arr) # Convert the NumPy array to PIL image
pil_image.save('test.png') # Save the image in PNG format
# Loading saved image then converting it to array to compare it against the original input data
test_output = Image.open('test.png')
#test_output_gray = test_output.convert('L')
test_output_gray = np.array(test_output)
print('shape = ' + str(test_output_gray.shape))
are_equal = np.array_equal(random_data_arr, test_output_gray) # True if random_data_arr and test_output_gray are equal
print('are_equal = ' + str(are_equal))
################################################################################
# Save image in WebP format.
# WebP does not support Grayscale - convert to RGB before saving
webp.save_image(pil_image.convert('RGB'), 'test.webp', lossless=True)
webp_output = webp.load_image('test.webp') # Load test.webp to PIL image
webp_output_gray = np.array(webp_output.convert('L')) # Convert to grayscale and to NumPy array
are_webp_equal = np.array_equal(random_data_arr, webp_output_gray) # True if random_data_arr and webp_output_gray are equal
print('are_webp_equal = ' + str(are_webp_equal))
################################################################################
关于python - 如何将8bit(0-255)数据表保存为图像文件,然后从图像中检索数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75162623/