Python中的图像预处理入门教程

147 阅读8分钟

Python中的图像预处理入门

在数据科学界,图像数据处理是最没有被充分开发的问题之一。每个开发者都有独特的方法。用于图像预处理的一些工具和平台包括Python、Pytorch、OpenCV、Keras、Tensorflow和Pillow。

简介

当建立一个机器学习/计算机视觉项目时,我们总是需要一件事就是数据。在这种情况下,图像数据。

不幸的是,与图像数据相关的一些问题包括复杂性、不精确性和不充分性。这就是为什么在建立计算机视觉模型之前,必须对数据进行预处理(清理并处理成所需的格式)以达到预期的效果。

在本教程中,我们将研究图像数据的预处理,它将图像数据转换为允许机器学习算法解决的形式。

它通常被用来提高模型的准确性,以及降低其复杂性。

有几种技术可用于预处理图像数据。例子包括:图像大小调整,将图像转换为灰度,以及图像增强。

前提条件

要完成本教程,需要以下条件。

  1. 一个Google[Colab]或[Kaggle]账户。你也可以使用Python和安装在你机器上的Jupyter笔记本。
  2. 一些关于Python的基本知识。

在本教程中,我们将使用[Google Colab]。因此,在创建一个新的笔记本后,第一步将是把数据加载到我们的Colab环境中。

将Google Drive安装到Colab上

我们将首先下载[数据],然后将其上传到我们的[Google Drive]。然后,我们将使用下面的代码将我们的驱动器安装到colab上。

from google.colab import drive
drive.mount("/content/drive/")

通过点击shift+enter键来运行单元格,并遵循以下说明。

  1. 点击显示的URL ,用你想要的数据驱动器所在的谷歌账户进行认证。

  2. 复制生成的授权代码,将其粘贴在URL下面的空白处,并点击回车键来执行。

导入数据集

下一步是将数据集加载到colab。为了导入数据集,我们首先需要导入一些必要的库。

# importing libraries
import tensorflow 
import keras  
import os
import glob 
from skimage import io 
import random 
import numpy as np
import matplotlib.pyplot as plt  
%matplotlib inline

一旦完成,我们将继续导入数据,这些数据现在在Google Drive上,使用下面的代码块。

# Importing and Loading the data into a data frame

dataset_path = '/content/drive/MyDrive/Animals'
class_names = ['Cheetah', 'Jaguar', 'Leopard', 'Lion','Tiger']

# apply glob module to retrieve files/pathnames  

animal_path = os.path.join(dataset_path, class_names[1], '*')
animal_path = glob.glob(animal_path)

现在,我们已经将数据集加载到我们的工作区,下一步将是将数据可视化。

为了验证我们的数据是否被正确加载,我们将尝试从数据集中访问一个图像文件。

# accessing an image file from the dataset classes
image = io.imread(animal_path[4])  

# plotting the original image
i, (im1) = plt.subplots(1)
i.set_figwidth(15)
im1.imshow(image)

通过执行上述代码块,我们将随机打印出数据集中的一个图像。

plotted image

数据预处理

现在我们已经完成了导入库和数据的工作,让我们继续进行数据预处理。

由于图像存在不同的格式,即自然的、假的、灰度的等等,我们需要在把它们送入神经网络之前考虑到并使其标准化。

在本教程中,我们将研究以下图像预处理技术。

  1. 灰度转换
  2. 正常化
  3. 数据扩增
  4. 图像标准化

在我们开始探索预处理技术之前,让我们首先探索一下原始图像的RGB通道。

# plotting the original image and the RGB channels  

i, (im1, im2, im3, im4) = plt.subplots(1, 4, sharey=True)
i.set_figwidth(20) 

im1.imshow(image)  #Original image
im2.imshow(image[:, : , 0]) #Red
im3.imshow(image[:, : , 1]) #Green
im4.imshow(image[:, : , 2]) #Blue
i.suptitle('Original & RGB image channels')

输出rgb

灰度转换

灰度是简单地将图像从彩色转换为黑白。它通常被用来降低机器学习算法的计算复杂性。

由于大多数图片不需要颜色来识别,使用灰度是明智的,它减少了图像中的像素数量,因此,减少了所需的计算量。

执行下面的代码,将原始图像转换为灰度。

gray_image = skimage.color.rgb2gray(image)
plt.imshow(gray_image, cmap = 'gray')

输出

gray_scale

:在解决某些问题时,将图像转换为灰度可能并不总是实用的。一些使用灰度不实际的例子包括:交通灯医疗诊断自动驾驶汽车农业等。知道是否使用它的最好方法取决于你的人类视觉能力,即识别没有颜色的物体。

归一化

也被称为数据重新缩放,它是将图像数据像素(强度)投射到一个预定的范围(通常是(0,1)(-1, 1) )的过程。这通常用在不同的数据格式上,你想把所有的数据归一化,以便在它们上面应用相同的算法。

归一化通常被应用于将图像的像素值转换为典型的或更熟悉的意义。

它的好处包括。

  • 对所有图像的公平性--例如,将所有图像缩放到[0,1]或[-1,1]的相等范围,允许所有图像对总损失的贡献相等,而不是当其他图像的高和低像素范围分别给予强和弱的损失。

  • 提供一个标准的学习率--由于高像素的图像需要一个低的学习率,而低像素的图像需要一个高的学习率,重新缩放有助于为所有图像提供一个标准学习率。

让我们编写下面的代码来规范我们的数据。

norm_image = (gray_image - np.min(gray_image)) / (np.max(gray_image) - np.min(gray_image))
plt.imshow(norm_image)

输出

normalization

数据扩增

数据扩增是对现有数据进行细微改动的过程,以增加其多样性,而无需收集新的数据。

它是一种用于扩大数据集的技术。标准的数据扩增技术包括水平和垂直翻转旋转裁剪剪切等。

执行数据增强有助于防止神经网络学习不相关的特征。这导致了更好的模型性能。

标准的数据增强技术包括水平和垂直翻转、旋转、裁剪、剪裁等。

有两种类型的增强。

  • 离线增强- 用于小型数据集。它被应用于数据预处理步骤中。我们将在本教程中介绍这种增强方法。

  • 在线增强--用于大型数据集。它通常是实时应用的。

在本教程中,我们将使用Keras的 ImageDataGenerator 类来增强我们的数据。这是因为它提供了一个快速和简单的方法来增强你的图像。

此外,它还支持诸如翻转、旋转、亮度变化等增强技术。

现在让我们来看看最常用的数据增强技术。

移位

这是一个水平或垂直移动图像像素的过程。

让我们看看下面这个水平移动的例子。

# import libraries

from numpy import expand_dims
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import ImageDataGenerator

# convert to numpy array
data = img_to_array(image)

# expand dimension to one sample
samples = expand_dims(image, 0)

# create image data augmentation generator
datagen = ImageDataGenerator(width_shift_range=[-200,200])

# create an iterator
it = datagen.flow(samples, batch_size=1)
fig, im = plt.subplots(nrows=1, ncols=3, figsize=(15,15))

# generate batch of images
for i in range(3):

    # convert to unsigned integers
    image = next(it)[0].astype('uint8')
 
    # plot image
    im[i].imshow(image) 

输出

shift

翻转

这是在垂直或水平情况下分别将像素的行或列翻转。

让我们做一个水平和垂直翻转的随机翻转。从[上面的代码]中,改变ImageDataGenerator的参数,如下所示。

# ImageDataGenerator for flipping
datagen = ImageDataGenerator(horizontal_flip=True, vertical_flip=True)

输出

flipping

旋转

这个过程涉及到将图像旋转一个指定的度数。

上面的代码中,改变ImageDataGenerator的参数,如下图所示。

datagen = ImageDataGenerator(rotation_range=20, fill_mode='nearest')

输出

rotation

改变亮度

这是一个增加或减少图像对比度的过程。

上面的代码中,改变ImageDataGenerator的参数,如下图所示。

datagen = ImageDataGenerator(brightness_range=[0.5,2.0])

输出

contrast

其他增强技术包括。

裁剪

这是一个创建原始图像的随机子集的过程,然后将其大小调整为原始图像的大小。

缩放

一个图像可以向内或向外缩放。当向外缩放图像时,图像变得比原来更重要,反之亦然。

标准化图像

标准化是一种对图像进行缩放和预处理的方法,使其具有相似的高度和宽度。它将数据重新缩放,使其标准差为1 (单位方差),平均值为0

标准化有助于提高数据的质量和一致性。

上面的代码中,改变ImageDataGenerator的参数,如下所示。

# creating the image data generator to standardize images
datagen = ImageDataGenerator(featurewise_center =True,
      featurewise_std_normalization = True)

结论

在探索了流行和常用的图像预处理技术后,现在剩下的就是对你的机器学习模型进行建模,以达到理想的高精确度和性能水平。因此,我们现在已经准备好进入构建自定义计算机视觉项目了。