Tensorflow.keras 的 ImageDataGenerator.flow_from_directory 如何缩放图像值?
How Does Tensorflow.keras's ImageDataGenerator.flow_from_directory scale image values?
我有一个经过训练的张量流模型,在制作训练数据库时,我使用了
from tensorflow.keras.preprocessing.image import ImageDataGenerator
ImageDataGenerator.flow_from_directory(organized_dir,
target_size=(image_dim, image_dim),
color_mode="grayscale",
batch_size=20,
shuffle=True,
follow_links=True)
(我只是展示我选择提供的参数,image_dim
等变量在别处定义)
当我在函数 returns 的 DirectoryIterator 对象上使用 next()
查看其中一批时,图像的像素值似乎从其原始 rgb 值 [0,255] 缩放到灰度 [0,1]。我想要它作为灰度,我的理解是 ML 模型在 0 到 1 之间的数字表现最好。太好了!
但是,现在我想在不同的图像上使用该模型。在 cv2
中打开它们并转换为灰度不会像 tensorflow 那样缩放像素值,它只是将颜色值保持在 [0,255] 而不是 [0,1]:
>>> z = cv2.imread("img.png")
>>> cv2.cvtColor(z, cv2.COLOR_BGR2GRAY)
array([[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
...,
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
所以,我要问的是如何使用与 tensorflow 数据集相同的转换来使图像使用从 [0,255] 到 [0,1] 的像素值。我在这里发现我可以规范化图像:。但我想使用 tensorflow 使用的确切 algorithm/parameters,这样我就可以最大限度地提高我在现实世界中的准确性。谢谢
关于 ImageDataGenerator 重新缩放图像像素值的说法不正确。根据文档,生成器有一个名为 rescale 的参数。对于此参数,文档说明:
rescale: rescaling factor. Defaults to None. If None or 0, no rescaling is applied,
otherwise we multiply the data by the value provided
(after applying all other transformations).
因此要将值从 0 重新调整为 1,然后使用
rescale=1/255
迁移学习中使用的许多模型要求像素值介于 -1 和 +1 之间。
对于这种情况,请使用
rescale=1/127.5-1
您正在阅读的图像可能已经重新调整了像素值。要测试您的图像是否已预先缩放,请使用
import numpy as np
import cv2
path_to_file= #specify the full path to the file
img=cv2.imread(path_to_file,0)# read in image as grayscale
max_pixel_value=np.max(img) # find maximum pixel value
min_pixel_value=np.min(img) # find minimum pixel value
print('max pixel value= ', max_pixel_value, ' min pixel value= ', min_pixel_value)
cv2.imread() 将图像读取为数据类型为 uint8 的 np.array。这就是为什么您拥有从 0 到 255 的所有值。要将值重新调整为 [0, 1],只需将它们除以 255
In[1]: import cv2
...: import numpy as np
In[2]: img = cv2.imread('some_image.jpg')
In[3]: img
Out[3]:
array([[[110, 89, 92],
[110, 89, 92],
[ 50, 29, 32],
...
In[4]: type(img)
Out[4]: numpy.ndarray
In[5]: img.dtype
Out[5]: dtype('uint8')
In[6]: img = (img / 255)
In[7]: np.min(img), np.max(img)
Out[7]: (0.0, 1.0)
In[8]: img
Out[8]:
array([[[0.43137255, 0.34901961, 0.36078431],
[0.43137255, 0.34901961, 0.36078431],
[0.19607843, 0.11372549, 0.1254902 ],
...
In[9]: img.dtype
Out[9]: dtype('float64')
这里引用了 ImageDataGenerator 的文档字符串:
rescale: rescaling factor. Defaults to None.
If None or 0, no rescaling is applied,
otherwise we multiply the data by the value provided
(after applying all other transformations)
所以您的问题的答案是:只需将您的数组乘以 1/255,您将得到与 ImageDataGenerator returns
相同的结果
我有一个经过训练的张量流模型,在制作训练数据库时,我使用了
from tensorflow.keras.preprocessing.image import ImageDataGenerator
ImageDataGenerator.flow_from_directory(organized_dir,
target_size=(image_dim, image_dim),
color_mode="grayscale",
batch_size=20,
shuffle=True,
follow_links=True)
(我只是展示我选择提供的参数,image_dim
等变量在别处定义)
当我在函数 returns 的 DirectoryIterator 对象上使用 next()
查看其中一批时,图像的像素值似乎从其原始 rgb 值 [0,255] 缩放到灰度 [0,1]。我想要它作为灰度,我的理解是 ML 模型在 0 到 1 之间的数字表现最好。太好了!
但是,现在我想在不同的图像上使用该模型。在 cv2
中打开它们并转换为灰度不会像 tensorflow 那样缩放像素值,它只是将颜色值保持在 [0,255] 而不是 [0,1]:
>>> z = cv2.imread("img.png")
>>> cv2.cvtColor(z, cv2.COLOR_BGR2GRAY)
array([[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
...,
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
所以,我要问的是如何使用与 tensorflow 数据集相同的转换来使图像使用从 [0,255] 到 [0,1] 的像素值。我在这里发现我可以规范化图像:
关于 ImageDataGenerator 重新缩放图像像素值的说法不正确。根据文档,生成器有一个名为 rescale 的参数。对于此参数,文档说明:
rescale: rescaling factor. Defaults to None. If None or 0, no rescaling is applied,
otherwise we multiply the data by the value provided
(after applying all other transformations).
因此要将值从 0 重新调整为 1,然后使用
rescale=1/255
迁移学习中使用的许多模型要求像素值介于 -1 和 +1 之间。 对于这种情况,请使用
rescale=1/127.5-1
您正在阅读的图像可能已经重新调整了像素值。要测试您的图像是否已预先缩放,请使用
import numpy as np
import cv2
path_to_file= #specify the full path to the file
img=cv2.imread(path_to_file,0)# read in image as grayscale
max_pixel_value=np.max(img) # find maximum pixel value
min_pixel_value=np.min(img) # find minimum pixel value
print('max pixel value= ', max_pixel_value, ' min pixel value= ', min_pixel_value)
cv2.imread() 将图像读取为数据类型为 uint8 的 np.array。这就是为什么您拥有从 0 到 255 的所有值。要将值重新调整为 [0, 1],只需将它们除以 255
In[1]: import cv2
...: import numpy as np
In[2]: img = cv2.imread('some_image.jpg')
In[3]: img
Out[3]:
array([[[110, 89, 92],
[110, 89, 92],
[ 50, 29, 32],
...
In[4]: type(img)
Out[4]: numpy.ndarray
In[5]: img.dtype
Out[5]: dtype('uint8')
In[6]: img = (img / 255)
In[7]: np.min(img), np.max(img)
Out[7]: (0.0, 1.0)
In[8]: img
Out[8]:
array([[[0.43137255, 0.34901961, 0.36078431],
[0.43137255, 0.34901961, 0.36078431],
[0.19607843, 0.11372549, 0.1254902 ],
...
In[9]: img.dtype
Out[9]: dtype('float64')
这里引用了 ImageDataGenerator 的文档字符串:
rescale: rescaling factor. Defaults to None. If None or 0, no rescaling is applied, otherwise we multiply the data by the value provided (after applying all other transformations)
所以您的问题的答案是:只需将您的数组乘以 1/255,您将得到与 ImageDataGenerator returns
相同的结果