如何将图像获取到数组,Tensorflow 1.9
How to get an image to array, Tensorflow 1.9
因此,出于系统特定原因,我必须使用 Tensorflow 1.9。
我想用包含图像的自定义数据集训练 cnn。
文件夹结构看起来非常像这样:
./
+ circles
- circle-0.jpg
- circle-1.jpg
- ...
+ hexagons
- hexagon-0.jpg
- hexagon-1.jpg
- ...
+ ...
因此我必须使用的示例使用 MNIST 并具有以下两行特定代码:
mnist_dataset = tf.keras.datasets.mnist.load_data('mnist_data')
(x_train, y_train), (x_test, y_test) = mnist_dataset
在我的工作中,我也不得不使用这种数据格式(x_train, y_train), (x_test, y_test)
,这似乎是很常见的。据我目前所知,这些数据集的格式是:(image_data, label)
,类似于 ((60000, 28, 28), (60000,))
,至少 MNIST 数据集是这样。这里的 image_data
应该是 dtype
uint8
(according to this post). I was able to find out, that a tf.data.Dataset()
对象看起来像我在这里需要的元组 (image_data, label)
.
到目前为止一切顺利。但是从这些信息中出现了一些我还没有弄清楚的问题,我想请求你的帮助:
(60000, 28, 28)
表示 60k 一个 28 x 28 图像值数组,对吗?
- 如果 1. 是正确的,我如何将我的图像(如我上面描述的目录结构中的图像)转换为这种格式?有没有一个函数可以生成一个我可以这样使用的数组?
- 我知道我需要某种生成器函数来获取所有带有标签的图像,因为在 Tensorflow 1.9 中
tf.keras.utils.image_dataset_from_directory()
似乎还不存在。
- 标签实际是什么样子的?例如,对于我的目录结构,我会有这样的东西:
(一)
File
Label
circle-0.jpg
circle
circle-233.jpg
circle
hexagon-1.jpg
hexagon
triangle-12.jpg
triangle
或 (B)
File
Label
circle-0.jpg
circle-0
circle-233.jpg
circle-233
hexagon-1.jpg
hexagon-1
triangle-12.jpg
triangle-12
,相应的图像已经转换为“(60000, 28, 28)
”格式?似乎我需要自己创建所有函数,因为似乎没有一个好的函数将像我这样的目录结构带到可以被 Tensorflow 1.9[=60= 使用的数据集],还是有?。我知道 tf.keras.preprocessing.image.ImageDataGenerator
and image_dataset_from_directory
as well as flow_from_directory()
,但是,它们似乎都没有给我带来我想要的数据集值元组格式。
非常感谢任何帮助!
您必须为此构建自定义数据生成器。如果您有两个数组,train_paths
包含图像的路径,train_labels
包含图像的标签,那么此函数 (datagen
) 将生成图像作为数组及其各自的标签作为元组 (image_array, label)
.
我还添加了一种方法 integer-encode 你的标签,用字典 encode_label
例如,train_paths
和 train_labels
应如下所示:
train_paths = np.array(['path/to/image1.jpg','path/to/image2.jpg','path/to/image3.jpg'])
train_labels = np.array(['circle','square','hexagon'])
路径'path/to/image1.jpg'的图片标签为'circle',路径'path/to/image2.jpg'的图片标签为'square'。
此生成器函数将 return 数据作为批处理,您也可以编写自定义增强技术(在 augment
函数内)
import tensorflow as tf
# Hyperparameters
HEIGHT = 224 # Image height
WIDTH = 224 # Image width
CHANNELs = 3 # Image channels
# This function will encode your labels
encode_label = {'hexagon':0, 'circle':1, 'square':2}
def augment(image):
# All your augmentation techniques are done here
return image
def encode_labels(labels):
encoded = []
for label in labels:
encoded.append(encode_label[label])
return encoded
def open_images(paths):
'''
Given a list of paths to images, this function loads
the images from the paths, then augments them, then returns it as a batch
'''
images = []
for path in paths:
image = tf.keras.preprocessing.image.load_img(path, target_size=(HEIGHT, WIDTH, CHANNELS))
image = np.array(image)
image = augment(image)
images.append(image)
return np.array(images)
# This is the data generator
def datagen(paths, labels, batch_size=32):
for x in range(0,len(paths), batch_size):
# Load batch of images
batch_paths = paths[x:x+batch_size]
batch_images = open_images(batch_paths)
# Load batch of labels
batch_labels = labels[x:x+batch_size]
batch_labels = encode_labels(batch_labels)
batch_labels = np.array(batch_labels, dtype='float').reshape(-1)
yield batch_images, batch_labels
如果您无法 tf.keras.preprocessing.image.load_img
在您的 tensorflow 版本中工作,请尝试使用替代方法加载图像并调整其大小。另一种方法是使用 matplotlib 加载图像,然后使用 skimage 调整它的大小。所以 open_images
函数是这样的:
import matplotlib
from skimage.transform import resize
def open_images(paths):
'''
Given a list of paths to images, this function loads
the images from the paths, then augments them, then returns it as a batch
'''
images = []
for path in paths:
image = matplotlib.image.imread(path)
image = np.array(image)
image = resize(image, (HEIGHT, WIDTH, CHANNELS))
image = augment(image)
images.append(image)
return np.array(images)
因此,出于系统特定原因,我必须使用 Tensorflow 1.9。 我想用包含图像的自定义数据集训练 cnn。 文件夹结构看起来非常像这样:
./
+ circles
- circle-0.jpg
- circle-1.jpg
- ...
+ hexagons
- hexagon-0.jpg
- hexagon-1.jpg
- ...
+ ...
因此我必须使用的示例使用 MNIST 并具有以下两行特定代码:
mnist_dataset = tf.keras.datasets.mnist.load_data('mnist_data')
(x_train, y_train), (x_test, y_test) = mnist_dataset
在我的工作中,我也不得不使用这种数据格式(x_train, y_train), (x_test, y_test)
,这似乎是很常见的。据我目前所知,这些数据集的格式是:(image_data, label)
,类似于 ((60000, 28, 28), (60000,))
,至少 MNIST 数据集是这样。这里的 image_data
应该是 dtype
uint8
(according to this post). I was able to find out, that a tf.data.Dataset()
对象看起来像我在这里需要的元组 (image_data, label)
.
到目前为止一切顺利。但是从这些信息中出现了一些我还没有弄清楚的问题,我想请求你的帮助:
(60000, 28, 28)
表示 60k 一个 28 x 28 图像值数组,对吗?- 如果 1. 是正确的,我如何将我的图像(如我上面描述的目录结构中的图像)转换为这种格式?有没有一个函数可以生成一个我可以这样使用的数组?
- 我知道我需要某种生成器函数来获取所有带有标签的图像,因为在 Tensorflow 1.9 中
tf.keras.utils.image_dataset_from_directory()
似乎还不存在。 - 标签实际是什么样子的?例如,对于我的目录结构,我会有这样的东西:
(一)
File | Label |
---|---|
circle-0.jpg | circle |
circle-233.jpg | circle |
hexagon-1.jpg | hexagon |
triangle-12.jpg | triangle |
或 (B)
File | Label |
---|---|
circle-0.jpg | circle-0 |
circle-233.jpg | circle-233 |
hexagon-1.jpg | hexagon-1 |
triangle-12.jpg | triangle-12 |
,相应的图像已经转换为“(60000, 28, 28)
”格式?似乎我需要自己创建所有函数,因为似乎没有一个好的函数将像我这样的目录结构带到可以被 Tensorflow 1.9[=60= 使用的数据集],还是有?。我知道 tf.keras.preprocessing.image.ImageDataGenerator
and image_dataset_from_directory
as well as flow_from_directory()
,但是,它们似乎都没有给我带来我想要的数据集值元组格式。
非常感谢任何帮助!
您必须为此构建自定义数据生成器。如果您有两个数组,train_paths
包含图像的路径,train_labels
包含图像的标签,那么此函数 (datagen
) 将生成图像作为数组及其各自的标签作为元组 (image_array, label)
.
我还添加了一种方法 integer-encode 你的标签,用字典 encode_label
例如,train_paths
和 train_labels
应如下所示:
train_paths = np.array(['path/to/image1.jpg','path/to/image2.jpg','path/to/image3.jpg'])
train_labels = np.array(['circle','square','hexagon'])
路径'path/to/image1.jpg'的图片标签为'circle',路径'path/to/image2.jpg'的图片标签为'square'。
此生成器函数将 return 数据作为批处理,您也可以编写自定义增强技术(在 augment
函数内)
import tensorflow as tf
# Hyperparameters
HEIGHT = 224 # Image height
WIDTH = 224 # Image width
CHANNELs = 3 # Image channels
# This function will encode your labels
encode_label = {'hexagon':0, 'circle':1, 'square':2}
def augment(image):
# All your augmentation techniques are done here
return image
def encode_labels(labels):
encoded = []
for label in labels:
encoded.append(encode_label[label])
return encoded
def open_images(paths):
'''
Given a list of paths to images, this function loads
the images from the paths, then augments them, then returns it as a batch
'''
images = []
for path in paths:
image = tf.keras.preprocessing.image.load_img(path, target_size=(HEIGHT, WIDTH, CHANNELS))
image = np.array(image)
image = augment(image)
images.append(image)
return np.array(images)
# This is the data generator
def datagen(paths, labels, batch_size=32):
for x in range(0,len(paths), batch_size):
# Load batch of images
batch_paths = paths[x:x+batch_size]
batch_images = open_images(batch_paths)
# Load batch of labels
batch_labels = labels[x:x+batch_size]
batch_labels = encode_labels(batch_labels)
batch_labels = np.array(batch_labels, dtype='float').reshape(-1)
yield batch_images, batch_labels
如果您无法 tf.keras.preprocessing.image.load_img
在您的 tensorflow 版本中工作,请尝试使用替代方法加载图像并调整其大小。另一种方法是使用 matplotlib 加载图像,然后使用 skimage 调整它的大小。所以 open_images
函数是这样的:
import matplotlib
from skimage.transform import resize
def open_images(paths):
'''
Given a list of paths to images, this function loads
the images from the paths, then augments them, then returns it as a batch
'''
images = []
for path in paths:
image = matplotlib.image.imread(path)
image = np.array(image)
image = resize(image, (HEIGHT, WIDTH, CHANNELS))
image = augment(image)
images.append(image)
return np.array(images)