使用Pytorch进行图像增强的综合教程

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

最近,在研究项目中,开始了解图像增强技术的重要性。该项目的目标是训练一个能够重建原始图像的鲁棒生成模型。所解决的问题是异常检测,这是一个相当具有挑战性的问题,因为数据量很小,而且模型不足以单独完成所有工作。

常见的场景是使用可用于训练的正常图像训练网络模型,并在包含正常图像和异常图像的测试集上评估其性能。

最初的假设是,生成模型应该很好地捕捉正态分布,但同时,它应该无法重建异常样本。如何验证这一假设?我们可以看到重建误差,异常图像的重建误差应该较高,而正常样本的重建误差应该较低。

在这篇文章中,将列出最好的数据增强技术,以增加数据集中图像的大小和多样性。其主要目的是提高模型的性能和泛化能力。

我们将探索简单的变换,如旋转、裁剪和高斯模糊,以及更复杂的技术,如高斯噪声和随机块。

图像增强技术:
1、简单变换
  • 调整大小

  • 灰度

  • 规范化

  • 随机旋转

  • 中心裁剪

  • 随机裁剪

  • 高斯模糊

2、更先进的技术
  • 高斯噪声

  • 随机块

  • 中心区域

1、表面裂纹数据集简介

c39f840b3c2bf1dabecfd1e2ec0e1d68.png

在本教程中,我们将使用表面裂纹检测数据集。你可以在此处或Kaggle上下载数据集:

https://data.mendeley.com/datasets/5y9wdsg2zt/2

从名称可以推断,它提供了有裂纹和无裂纹曲面的图像。因此,它可以作为异常检测任务的数据集,其中异常类由有裂纹的图像表示,而正常类由无裂纹的表面表示。

该数据集包含4000幅有缺陷和无缺陷表面的彩色图像。这两个类都有训练和测试集。此外,以227×227像素的分辨率获取每个数据集图像。

2、简单变换

本节包括torchvision中可用的不同转换模块。在深入研究之前,我们从训练数据集中导入模块和一个没有缺陷的图像。

from PIL import Image
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import sys
import torch
import numpy as np
import torchvision.transforms as T

plt.rcParams["savefig.bbox"] = 'tight'
orig_img = Image.open(Path('../input/surface-crack-detection/Negative/00026.jpg'))
torch.manual_seed(0)
data_path = '../input/surface-crack-detection/'
diz_class = {'Positive':'Crack','Negative':'No crack'}

让我们显示图像的尺寸:

np.asarray(orig_img).shape  #(227, 227, 3)

这意味着我们有一个227x227的图像,有3个通道。

调整大小

由于图像具有很高的高度和宽度,因此在将其传递给神经网络之前,需要降低维数。例如,我们可以将227x227图像调整为32x32和128x128图像。

resized_imgs = [T.Resize(size=size)(orig_img) for size in [32,128]]
plot(resized_imgs,col_title=["32x32","128x128"])
f969a518352aac7a09e168b6a60b2bfd.png

值得注意的是,当我们获得一幅32x32的图像时,我们会失去分辨率,而128x128的尺寸似乎可以保持样品的高分辨率。

灰度等级

RGB图像可能很难管理。因此,将图像转换为灰度可能很有用:

gray_img = T.Grayscale()(orig_img)
plot([gray_img], cmap='gray', col_title=["Gray"])
cd22cdb192d8ab9d92df17b0fa3931f1.png
规范化

规范化是一种有效的方法,可以加快基于神经网络结构的模型的计算速度,加快学习速度。规范化图像有两个步骤:

  • 我们从每个输入通道中减去通道平均值

  • 稍后,我们将其除以通道标准差。

我们可以显示原始图像及其规范化版本:

normalized_img = T.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))(T.ToTensor()(orig_img)) 
normalized_img = [T.ToPILImage()(normalized_img)]
plot(normalized_img, col_title=["Standard normalize"])
f8edd1ebbca6845f92193e5ea5a2c557.png
随机旋转

随机旋转方法以随机角度旋转图像。

rotated_imgs = [T.RandomRotation(degrees=d)(orig_img) for d in range(50,151,50)]
plot(rotated_imgs, col_title=["Rotation 50","Rotation 100","Rotation 150"])
0fc76f4ac31378ca95da02c9e837440b.png
中心裁剪

我们使用T.CenterCrop方法裁剪图像的中心部分,其中需要指定裁剪大小。

center_crops = [T.CenterCrop(size=size)(orig_img) for size in (128,64, 32)]
plot(center_crops,col_title=['128x128','64x64','32x32'])
558d1156820f4fe1764c33fa774f2fde.png

当图像的边界中有一个大背景,而分类任务根本不需要这个背景时,这种转换非常有用。

随机裁剪

我们没有裁剪图像的中心部分,而是通过T.RandomCrop方法随机裁剪图像的一部分,该方法将裁剪的输出大小作为参数。

random_crops = [T.RandomCrop(size=size)(orig_img) for size in (832,704, 256)]
plot(random_crops,col_title=['832x832','704x704','256x256'])
964556d89a09c6a917374b682e01f2fd.png
高斯模糊

我们使用高斯核对图像进行高斯模糊变换。这种方法有助于降低图像的清晰度和清晰度,然后将生成的图像输入到神经网络中,神经网络在样本的学习模式方面变得更加稳健。

blurred_imgs = [T.GaussianBlur(kernel_size=(51, 91), sigma=sigma)(orig_img) for sigma in (3,7)]
plot(blurred_imgs)
37233addab5e3add435fe56313446db6.png

3、更先进的技术

前面展示了PyTorch提供的简单转换示例。现在,我们将重点讨论从零开始实现的更复杂的技术。

高斯噪声

高斯噪声是一种常用的向整个数据集添加噪声的方法,它迫使模型学习数据中包含的最重要信息。

它包括注入高斯噪声矩阵,高斯噪声矩阵是从高斯分布中提取的随机值矩阵。稍后,我们将在0和1之间剪裁样本。噪声因子越高,图像的噪声越大。

def add_noise(inputs,noise_factor=0.3):
     noisy = inputs+torch.randn_like(inputs) * noise_factor
     noisy = torch.clip(noisy,0.,1.)
     return noisy
    
noise_imgs = [add_noise(T.ToTensor()(orig_img),noise_factor) for noise_factor in (0.3,0.6,0.9)]
noise_imgs = [T.ToPILImage()(noise_img) for noise_img in noise_imgs]
plot(noise_imgs, col_title=["noise_factor=0.3","noise_factor=0.6","noise_factor=0.9"])
b8dbe293f232db5ccd7c08e85d677f6c.png
随机块

正方形补丁随机应用在图像中。这些补丁的数量越多,神经网络解决问题的难度就越大。

def add_random_boxes(img,n_k,size=32):
    h,w = size,size
    img = np.asarray(img)
    img_size = img.shape[1]
    boxes = []
    for k in range(n_k):
        y,x = np.random.randint(0,img_size-w,(2,))
        img[y:y+h,x:x+w] = 0
        boxes.append((x,y,h,w))
    img = Image.fromarray(img.astype('uint8'), 'RGB')
    return img

blocks_imgs = [add_random_boxes(orig_img,n_k=i) for i in (10,20)]
plot(blocks_imgs,col_title=["10 black boxes","20 black boxes"])
799edafb4143d9a15c83ee23ceb2cf4f.png
中心区域

这是一种非常简单的方法,可以使模型更一般化。它包括在图像的中心区域添加一个补丁块。

def add_central_region(img,size=32):
    h,w = size,size
    img = np.asarray(img)
    img_size = img.shape[1] 
    img[int(img_size/2-h):int(img_size/2+h),int(img_size/2-w):int(img_size/2+w)] = 0
    img = Image.fromarray(img.astype('uint8'), 'RGB')
    return img
  
central_imgs = [add_central_region(orig_img,size=s) for s in (32,64)]
plot(central_imgs,col_title=["32","64"])
df43b0c7c2185d79b1e6a33074bc30cf.png
最后的想法:

希望你发现本教程很有用。目的是对基于神经网络的图像增强方法进行概述,以解决模型的泛化问题。代码位于GitHub上:

https://github.com/eugeniaring/Medium-Articles/blob/main/Anomaly%20Detection/image-augmentation-on-crack-images.ipynb

感谢阅读!

好消息!

小白学视觉知识星球

开始面向外开放啦👇👇👇

 
 

23c5ed936071b01e6f27755f3a3afe7f.jpeg

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。


下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。


交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值