keras如何批量读取图片_python 图片读取 常用操作方法

图片读取与保存

cv2.imread

import cv2

im = cv2.imread(img_path) # 若无法读取,返回 None, cv2.imread(path, flags) flags: cv2.IMREAD_COLOR, cv2.IMREAD_GRAYSCALE, cv2.IMREAD_UNCHANGED

type(im) # numpy.ndarray

im.shape # 高,宽,通道 (1047, 1920, 3)

''' cv2.imread 导入的图片格式为 BGR,而不是平常的 RGB, 通过matplotlit.pyplot.imshow 可以看出 BGR 与 RGB 的区别'''

im_RGB = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) # 将 BGR 格式转换为 RGB 格式, cv2.COLOR_BGR2GRAY 转换为灰度格式, cv2.COLOR_BGR2HSV 转换为 HSV 格式

im_resize = cv2.resize(im, (128, 128))

''' 保存图片, cv2.imwrite()

cv2.imwrite('new_.jpg', im) # 注意这里需要保存 BGR 格式的图片,若是保存 RGB 格式的,图片颜色显示不对。

##对于JPEG,其表示的是图像的质量,用0-100的整数表示,默认为95。 ##注意,cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int。

cv2.imwrite('new_.jpg', img1, [int(cv2.IMWRITE_JPEG_QUALITY), 5])

##对于png图片,第三个参数表示的是压缩级别。##cv2.IMWRITE_PNG_COMPRESSION,从0到9,压缩级别越高,图像尺寸越小。默认级别为3

cv2.imwrite('new_.png', img1, [int(cv2.IMWRITE_JPEG_QUALITY), 5])

''' 显示图片 '''

cv2.namedWindow("im")

cv2.imshow('im',image_gray)

cv2.waitKey(0)

cv2.destroyAllWindows()

PIL.Image (Python Image Library)

from PIL import Image

im = image.open(img_path)

print(im.format) # 'JPEG'

print(im.size) # '(464,331) (宽,高)

print(im.mode) # RGB

im.show() # 显示图片

import numpy as np

np_img = np.array(im) # 将PIL的Image格式转换为 ndarray 格式 (高,宽,通道)

im.resize((128, 128)) # 修改图片大小

im.save('new_image.png') # 保存图片

import matplotlib.pyplot as plt

plt.imshow(im)

matplotlib.image.imread

import matplotlib.image as mpimg

import numpy as np

im = mpimg.imread(img_path)

type(im) # numpy.ndarray, RGB 格式。

im.shape # 高,宽,通道 (1047, 1920, 3)

plt.savefig('new_.jpg')

from skimage import io # scikit-image

from skimage import io

im = io.imread(img_path)

im.shape # 高,宽,通道 (1047, 1920, 3)

type(im) # numpy.ndarray, RGB 格式

io.imsave('new_.jpg', im)

io.imshow(im)

plt.imshow(im)

import imageio

批量获取图片:

import glob

''' glob 可以查找符合特定规则的文件路径名。查找文件只用到三个匹配符:”*”, “?”, “[]”;”*”匹配0个或多个字符;

”?”匹配单个字符;”[]”匹配指定范围内的字符,如:[0-9]匹配数字;

glob.glob返回所有匹配的文件路径列表。

它只有一个参数pathname,定义了文件路径匹配规则,这里可以是绝对路径,也可以是相对路径。 '''

glob.glob(os.path.join(folder, '*.png')) # 获取文件列表

import skimage.io as io

from skimage import data_dir

s = 'd:\pic\*.jpg'

coll = io.ImageCollection(s) # coll 是个图片集合, 可以通过列表索引获取具体的图片, 可以有第二个参数 load_func,可以是自定义的函数。

from torchvision.datasets import ImageFolder

from torch.utils.data import DataLoader

from torchvision import transforms

'''

DataLoader 能够自动生成一个多线程的迭代器,针对 Dataset 数据集, 利用torch自带的数据集加载后就是Dataset数据集,或者通过 ImageFolder 将自己硬盘上的图片加载成 Dataset 格式。、

'''

transform = transforms.Compose([

transforms.CenterCrop(size),

transforms.RandomCrop(size, padding = 0),

transforms.Resize((256, 256)),

transforms.RandomVerticalFlip(p=0.5),

transforms.RandomHorizontalFlip(p=0.5),

**transforms.ToTensor(),**

transforms.Normalize(mean = (0.5, 0.5, 0.5), std = (0.5, 0.5, 0.5))

dset = ImageFolder(root = 'E:\pic\', transform = None, transform = transform, loader = default_loader) # 只能取 root 路径下的直接文件夹作为分类,再往下的子文件夹会归到一类中。 dset文件类型: torchvision.datasets.folder.ImageFolder;

len(dset) # 子文件夹的数量

dset[0] # (, 0), 这里 如果没有transforms.ToTensor(), 则为 PIL.Image 格式,如果有 transforms.ToTensor(), 则为Tensor 格式。 如果想用 DataLoader,则必须有 transforms.ToTensor()。

dset[0][0] # 图片

dset[0][1] # 索引

'''

把一个取值范围是[0,255]的PIL.Image或者shape为(H,W,C)的numpy.ndarray,转换成形状为[C,H,W],取值范围是[0,1.0]的torch.FloadTensor

'''

'''

他有以下成员变量:

* self.classes - 用一个list保存, 保存分类的名称(文件夹的名称) ['cde', 'check']

* self.class_to_idx - 类名对应的 索引,分类名称与索引的对应关系) {'cde': 0, 'check': 1}

* self.imgs - 保存(img-path, class) tuple的list [('E:\\pic\\cde\\照片 558.jpg', 0), ('E:\\pic\\check\\abc\\image.png', 1)]

'''

dataloader = DataLoader(dset, batch_size = 2, shuffle = True, num_workers = 3)

dataiter = iter(dataloader)

'''

- dataloader本质是一个可迭代对象,使用iter()访问,不能使用next()访问;

- 使用iter(dataloader)返回的是一个迭代器,然后可以使用next访问;

- 也可以使用`for inputs, labels in dataloaders`进行可迭代对象的访问;

- 一般我们实现一个datasets对象,传入到dataloader中;然后内部使用yeild返回每一次batch的数据;

'''

keras.preprocessing.image.load_img

import numpy as np

from keras.utils import to_categorical

from keras.preprocessing import image

from keras.applications.resnet50 import ResNet50 # 加载默认模型,如果有已经存在,则直接加载,否则下载。 路径:C:\Users\你的用户名\.keras\models

file_path = './dogs-vs-cats/train/cat.1.jpg'

img = image.load_img(file_path, target_size = (224, 224))

type(img) # PIL.Image.Imgage

x = image.img_to_array(img) # 转换为 numpy.ndarray 格式 (224, 224, 3)

x = np.expand_dims(x, axis = 0) # 增加一个维度 (1, 224, 224, 3), 模型本身要求输入尺寸是(None, 224, 224, 3),这个None表示batch,意思是你要输入多少张图片模型是不知道的,所以就用None来表示,而当你输入图片的时候,shape必须跟模型输入的shape保持一致才能输入。

model = ResNet50(weights='imagenet')

model.predict(x)

keras 多张图片:

'''

以下代码适用模型预测。多张图片输入思想也很简单,就是把同一个类别的图片文件夹底下所有的图片用for循环load进来,然后加到一个list里面,最后concatenate起来。

适用情况:

图片数量:多张

适用场景:模型预测

图片尺寸:统一

'''

import numpy as np

from keras.preprocessing import image

from keras.applications.resnet50 import ResNet50

import glob

file_path = 'E:/pic/'

f_names = glob.glob(file_path + '*.jpg')

imgs = []

for i in range(len(f_names)):

img = image.load_img(f_names[i], target_size=(224, 224))

arr_img = image.img_to_array(img)

arr_img = np.expand_dims(arr_img, axis=0)

imgs.append(arr_img)

x = np.concatenate([x for x in imgs]) # concatenate的作用是把shape为(0, 224, 224, 3)的每张图片tensor,打包成shape为(batch, 224, 224, 3)的tensor,这样就能实现批量预测或批量训练了。

print("predicting...")

model = ResNet50(weights='imagenet')

y = model.predict(x)

print("Completed!")

很多情况下,你并不能使用以上这些方法来直接输入数据去训练或者预测,原因是你的数据集太大了,没办法把所有的图片都载入到内存当中。那keras的data generator就派上用场了,当你的模型需要训练数据的时候,generator会自动从cpu生成一批图片,喂到GPU里面让模型进行训练,依次循环,直到训练结束。

适用情况:

图片数量:大批量

适用场景:模型预测、训练

图片尺寸:可不统一

'''

ImageDataGenerator:

通过实时数据增强生成张量图像数据批次。数据将不断循环(按批次)。

有很多参数对应于图像处理,如图像翻转,均值设为0,除以标准差,旋转,缩放,通道转换,填充,自定义函数。

其中 data_format:图像数据格式,{"channels_first", "channels_last"} 之一。"channels_last" 模式表示图像输入尺寸应该为 (samples, height, width, channels),"channels_first" 模式表示输入尺寸应该为 (samples, channels, height, width)。默认为 在 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值。如果你从未设置它,那它就是 "channels_last"。

flow_from_directory:

生成 (x, y) 元组的 DirectoryIterator,其中 x 是一个包含一批尺寸为 (batch_size, *target_size, channels)的图像的 Numpy 数组,y 是对应标签的 Numpy 数组。

directory: 目标目录的路径。

* target_size: 整数元组 (height, width),默认:(256, 256)。所有的图像将被调整到的尺寸。

* color_mode: "grayscale", "rbg" 之一。默认:"rgb"。图像是否被转换成 1 或 3 个颜色通道。

**class_mode: "categorical", "binary", "sparse", "input" 或 None 之一。默认:"categorical"。决定返回的标签数组的类型: ------- 这里需要与model.compile中的损失函数相对应,既标签格式。**

* "categorical" 将是 2D one-hot 编码标签,

* "binary" 将是 1D 二进制标签,"sparse" 将是 1D 整数标签,

* "input" 将是与输入图像相同的图像(主要用于自动编码器)。

* 如果为 None,不返回标签(生成器将只产生批量的图像数据,对于 model.predict_generator(), model.evaluate_generator() 等很有用)。请注意,如果 class_mode 为 None,那么数据仍然需要驻留在 directory 的子目录中才能正常工作。

其他 有 batch_size,默认32, shuffle,保存 等等。

'''

from keras.preprocessing.image import ImageDataGenerator

from keras.applications.resnet50 import ResNet50

trn_path = './dogs-vs-cats/train/'

val_path = './dogs-vs-cats/val/'

generator = ImageDataGenerator()

trn_data = generator.flow_from_directory(trn_path, batch_size=32, target_size=(224, 224), class_mode='sparse')

val_data = generator.flow_from_directory(val_path, batch_size=32, target_size=(224,224), class_mode='sparse')

model = ResNet50(weights='imagenet')

model.compile(optimizer='sgd', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit_generator(trn_data, steps_per_epoch=200, epochs=50, validation_data=val_data, validation_steps=80)

图像处理方法

压缩数据中维度为1的维度, numpy.squeeze()

模型是不能直接对图片进行卷积操作的,必须先转化为numpy数组才能输入模型里面去,而且如果数据集的图片尺寸不统一,也有不同的操作细节。

keras 模型保存路径: C:\Users\你的用户名.keras\models

notop代表是否包括顶层的全连接层,默认include_top=True,包括全连接层。

tf -- tensorflow 或者 CNTK

th -- theano

你可能感兴趣的:(keras如何批量读取图片)