图像预处理

一、PIL 库

对于图像识别,大量的工作在于图像的处理,处理效果好,那么才能很好地识别。因此,良好的图像处理是识别的基础。在 Python中 有一个优秀的图像处理框架,就是 PIL 库。
PIL 非常适合于图像归档以及图像的批处理任务。你可以进行旋转、镜像、对比度、亮度、平移、锐度、模糊、裁剪和缩放等数据增强操作。
PIL 包括了基础的图像处理函数,包括对点的处理,使用众多的卷积核 (convolution kernels) 做过滤 (filter) ,还有颜色空间的转换。PIL 库同样支持图像的大小转换,图像旋转,以及任意的仿射变换。PIL还有一些直方图的方法,允许你展示图像的一些统计特性。这个可以用来实现图像的自动对比度增强,还有全局的统计分析等。

PIL 库主要用途

在这里插入图片描述

1、 Image 类

Image 是 PIL 中最重要的类,用于从文件加载图像、处理其他图像、从 scratch 创建图形等。

(1)加载图像

PIL 库支持大量图片格式。使用 Image 模块的 open() 函数从磁盘读取文件。你不需要知道文件格式就能打开它,PIL能够根据文件内容自动确定确定文件格式

从文件加载图像,若打开错误返回 IOError:

from PIL import Image
im = Image.open('"E:\mywife.jpg"')    ##文件存在的路径
im.show()    ##展示图片

需要知道的是在win的环境下im.show的方式为win自带的图像显示应用。打开并确认给定的图像文件。这个是一个懒操作;该函数只会读文件头,而真实的图像数据直到试图处理该数据才会从文件读取(调用load()方法将强行加载图像数据)。如果变量mode被设置,那必须是“r”。用户可以使用一个字符串(表示文件名称的字符串)或者文件对象作为变量file的值。

从打开的文件中读取:

with open("hopper.ppm", "rb") as fp:
    im = Image.open(fp)

如果是从二进制流中读取,则需要先通过 io 转换成文件流,或者使用 StringIO:

import io
im = Image.open(io.BytesIO(buffer))
import StringIO
im = Image.open(StringIO.StringIO(buffer))

从 tar 中读取:

from PIL import Image, TarIO
fp = TarIO.TarIO("Tests/images/hopper.tar", "hopper.jpg")
im = Image.open(fp)

(2)图片属性

成功加载后会返回一个 Image 对象,有以下属性:

format: 判断图片来源,即ppm/png等 (若不是从文件读取则返回None);
size:查看宽度和高度(二元组tuple,单位是px);
mode: 定义图像波段数与名称(像素类型和深度),常见有 L 灰度图像,RGP 真彩色图像,CMYK 出版图像

print(im.format, im.size, im.mode)
# jpg (512, 512) RGB

(3)图片显示

# 自带方法:
im.show()
# 使用 matplotlib 显示:
import matplotlib.pyplot as plt
plt.imshow(im)
plt.show()

(4)保存图像

im.save(outfile,options…)
im.save(outfile, format, options…)

若要保存文件,则使用 Image 类的 save() 方法,此时保存文件的文件名就变得十分重要了,除非指定格式,否则这个库将会以文件名的扩展名作为格式保存。save() 方法的 format 参数可以指定文件格式进行保存图像。如果变量format缺省,如果可能的话,则从文件名称的扩展名判断文件的格式。该方法返回为空。关键字options为文件编写器提供一些额外的指令。如果编写器不能识别某个选项,它将忽略它。用户可以使用文件对象代替文件名称。在这种情况下,用户必须指定文件格式。

from PIL import Image
im = Image.open("E:\mywife.jpg")
print(im)
im.save("E:\mywife.png")     ## 将"E:\mywife.jpg"保存为"E:\mywife.png"
im = Image.open("E:\mywife.png")  ##打开新的png图片
print(im.format, im.size, im.mode)

在这里插入图片描述

2、 图像处理

(1)剪切、粘贴

crop():从图像中提取子矩形。box坐标分别是(左,上,右,下)的位置,下例取出的是 300*300 像素的矩阵。

paste():粘贴。粘贴区域是大小必须完全匹配,但模式不需要匹配(模式在粘贴时会自动转换)。粘贴时可以选择透明度,0 对应完全透明,255对应不透明(默认)。

from PIL import Image
im = Image.open("E:\mywife.jpg")
box = (300, 100, 700, 700)              ##确定拷贝区域大小
region = im.crop(box)                   ##将im表示的图片对象拷贝到region中,大小为box
region.show()

(2)图像分离与融合

split():用于对图像进行波段拆分,如针对RGB图像,拆分后将生成3幅单波段图像,对单波段图像则返回本身。
merge():用于将多个波段图像合并成新图像。

r, g, b = im.split()     # 获得三个通道的图像
plt.imshow(r)
plt.show()  # 打印r通道的图像
im = Image.merge("RGB", (b, g, r))
PIL.image.alpha_composite(im1,im2) 
PIL.image.blend(im1,im2,alpha) 
PIL.Image.composite(im1,im2,mask) 

这三个方法都属于图片的合成或者融合。都要求im1和im2的mode和size要一致,alpha代表图片透明度的意思,而 mask 的 mode 可以为”1”、”L”或者”RGBA”,size必须和im1、im2是一致的

# coding:utf-8 -*-
from PIL import Image
# 图片合成

# PIL的alpha_composite(im1,im2) 图像通道融合
# im2要和im1的size和mode一致,且要求格式为RGBA
im1 = Image.open("test.png")
im2 = Image.open("test2.png")

newim1 = Image.alpha_composite(im1, im2) # 将im2合成到im1中,如果其一是透明的,才能看到结果,不然最终结果只会显示出im2
newim1.show()
#print(im1.mode)

# -----------------------------------------
# image.blend(im1, im2, alpha)
# alpha为透明度
newim2 = Image.blend(im1, im2, 0.2)  # im1和im2按照第一张80%的透明度,第二张20%的透明度,合成为一张。
newim2.show()

# -----------------------------------------
mask = Image.open("mask.png")
newim3 = Image.composite(im2, im1, mask)
newim3.show()

(3)几何变换

resize():给定目标尺寸元组,对图像进行拉伸或压缩;
rotate():给定旋转角度,对图像进行逆时针旋转;
transpose():使用一些固定方法对图像进行变换;

out = im.resize((128, 128))
out = im.rotate(45) # degrees counter-clockwise
out = im.transpose(Image.FLIP_LEFT_RIGHT)
out = im.transpose(Image.FLIP_TOP_BOTTOM)
out = im.transpose(Image.ROTATE_90)
out = im.transpose(Image.ROTATE_180)
out = im.transpose(Image.ROTATE_270)

(4)颜色模式转换

convert():对图像进行不同颜色模型的转换,如常用的 L 与 RGB 之间的转换

im = Image.open("hopper.ppm").convert("L")

3、 图像增强

(1)滤波器

ImageFilter 模块包含许多可以与 filter() 方法一起使用的预定义滤波器。

from PIL import ImageFilter
out = im.filter(ImageFilter.DETAIL)

返回一个使用给定滤波器处理过的图像的拷贝。在ImageFilter 模块中,预先定义了很多增强滤波器,可以通过 filter() 函数使用,预定义滤波器包括:
● BLUR:模糊滤波
● CONTOUR:轮廓滤波
● DETAIL:细节滤波
● EDGE_ENHANCE:边界增强滤波
● EDGE_ENHANCE_MORE:深度边缘增强滤波
● EMBOSS:浮雕滤波
● FIND_EDGES:寻找边界滤波(找寻图像的边界信息)
● SMOOTH:平滑滤波
● SMOOTH_MORE:深度平滑滤波
● SHARPEN:锐化滤波
● GaussianBlur:高斯模糊
● UnsharpMask:反锐化掩码滤波(radius:模糊半径;percent:反锐化强度(百分比);threshold:被锐化的最小亮度)
● Kernel:卷积核滤波 (size:核的大小;kernel:核权值序列如33的为;scale:缩放因子;offset:偏移量)
● RankFilter:排序滤波 (size:核的大小;rank:排序序号)
● Kernel:卷积核滤波 (size:核的大小;kernel:核权值序列如33的为;scale:缩放因子;offset:偏移量)
● MinFilter:最小值滤波器
● MedianFilter:中值滤波
● MaxFilter:最大值滤波
● ModeFilter:模式滤波

from PIL import Image
from PIL import ImageFilter                         ## 调取ImageFilter
imgF = Image.open("E:\mywife.jpg")
bluF = imgF.filter(ImageFilter.BLUR)                ##均值滤波
conF = imgF.filter(ImageFilter.CONTOUR)             ##找轮廓
edgeF = imgF.filter(ImageFilter.FIND_EDGES)         ##边缘检测
imgF.show()
bluF.show()
conF.show()
edgeF.show()

(2)点操作

point()方法可用于转换图像的像素值(例如图像对比度操作)。在大多数情况下,期望一个参数的函数对象可以传递给此方法。每个像素都根据该功能进行处理。

# split the image into individual bands
source = im.split()

R, G, B = 0, 1, 2

# 处理单个色带,将 red < 100 赋 0 否则 255
mask = source[R].point(lambda i: i < 100 and 255)

# 处理单个色带,将 green 变成原来 0.7 倍
out = source[G].point(lambda i: i * 0.7)

# paste the processed band back, but only where red was < 100
source[G].paste(out, None, mask)

# build a new multiband image
im = Image.merge(im.mode, source)

(3)增强

对于更高级的图像增强,您可以使用 ImageEnhance 模块中的类。从图像创建后,可以使用增强对象快速尝试不同的设置。
您可以用这种方式调整对比度,亮度,色彩平衡和清晰度。

from PIL import ImageEnhance

enh = ImageEnhance.Contrast(im)
enh.enhance(1.3).show("30% more contrast")

ImageEnhance 模块提供了一些用于图像增强的类,所有的增强类都实现了一个通用的接口,包括一个方法:

 enhancer.enhance(factor) ⇒ image 

该方法返回一个增强过的图像。变量factor是一个浮点数,控制图像的增强程度。变量factor为1将返回原始图像的拷贝;factor值越小,颜色越少(亮度,对比度等),更多的价值。对变量facotr没有限制。
加强器包括色彩平衡,亮度平衡,对比度,锐化度等。通过使用这些加强器,可以很轻松的做到图片的色彩调整,亮度调整,锐化等操作,google picasa中提供的一些基本的图片加强功能都可以实现。

颜色加强 Color 类

用于调整图片的色彩平衡,相当于彩色电视机的色彩调整。

im02 =Image.open("D:\\Code\\Python\\test\\img\\test02.jpg")
im_1 = ImageEnhance.Color(im02).enhance(0.1) 
im_5 = ImageEnhance.Color(im02).enhance(0.5) 
im_8 =ImageEnhance.Color(im02).enhance(0.8) 
im_20 = ImageEnhance.Color(im02).enhance(2.0) 

亮度加强 Brightness 类

用于调整图片的亮度。增强因子为0.0将产生黑色图像;为1.0将保持原始图像。

对比度加强 Contrast 类

用于调整图片的对比度,相当于彩色电视机的对比度调整。增强因子为0.0将产生纯灰色图像;为1.0将保持原始图像。

锐化度加强 Sharpness 类

锐度增强类用于调整图像的锐度。增强因子为0.0将产生模糊图像;为1.0将保持原始图像,为2.0将产生锐化过的图像。

4、 图像序列

Python图像库包含对图像序列(也称为动画格式)的一些基本支持。支持的序列格式包括FLI/FLC, GIF和一些实验格式。 TIFF文件也可以包含多个帧。
当你打开一个序列文件时,PIL自动加载序列中的第一帧。您可以使用seek和tell方法在不同的帧之间移动。注意当前版本库中的大多数驱动程序只允许您寻找下一帧。要倒回文件,您可能必须重新打开它。

读序列:

from PIL import Image

im = Image.open("animation.gif")
im.seek(1) # skip to the second frame

try:
    while 1:
        im.seek(im.tell()+1)
        # do something to im
except EOFError:
    pass # end of sequence

使用for遍历:

from PIL import ImageSequence
for frame in ImageSequence.Iterator(im):
    # ...do something to frame...

二、pytorch 的 transforms 模块

pytorch中的transforms模块中包含了很多种对图像数据进行变换的函数,这些都是在我们进行图像数据读入步骤中必不可少的。
ransforms 的处理方法,总结有四大类:

在这里插入图片描述
在这里插入图片描述

1、裁剪——Crop

(1)随机裁剪:transforms.RandomCrop

class torchvision.transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode=‘constant’)

功能:依据给定的size随机裁剪
参数:
size- (sequence or int),若为sequence,则为(h,w),若为int,则(size,size)
padding-(sequence or int, optional),此参数是设置填充多少个pixel。 当为int时,图像上下左右均填充int个,例如padding=4,则上下左右均填充4个pixel,若为3232,则会变成4040。 当为sequence时,若有2个数,则第一个数表示左右扩充多少,第二个数表示上下的。当有4个数时,则为左,上,右,下。
fill- (int or tuple) 填充的值是什么(仅当填充模式为constant时有用)。int时,各通道均填充该值,当长度为3的tuple时,表示RGB通道需要填充的值。
padding_mode- 填充模式,这里提供了4种填充模式,1.constant,常量。2.edge 按照图片边缘的像素值来填充。3.reflect,暂不了解。 4. symmetric,暂不了解。

(2)中心裁剪:transforms.CenterCrop

class torchvision.transforms.CenterCrop(size) 

功能:依据给定的size从中心裁剪
参数:
size- (sequence or int),若为sequence,则为(h,w),若为int,则(size,size)

(3)随机长宽比裁剪 transforms.RandomResizedCrop

class torchvision.transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=2)

功能:随机大小,随机长宽比裁剪原始图片,最后将图片resize到设定好的size
参数:
size- 输出的分辨率 scale- 随机crop的大小区间,如scale=(0.08, 1.0),表示随机crop出来的图片会在的0.08倍至1倍之间。
ratio- 随机长宽比设置 interpolation- 插值的方法,默认为双线性插值(PIL.Image.BILINEAR)

(4)上下左右中心裁剪:transforms.FiveCrop

class torchvision.transforms.FiveCrop(size) 

功能:对图片进行上下左右以及中心裁剪,获得5张图片,返回一个4D-tensor
参数:
size- (sequence or int),若为sequence,则为(h,w),若为int,则(size,size)

(5)上下左右中心裁剪后翻转: transforms.TenCrop

class torchvision.transforms.TenCrop(size, vertical_flip=False)

功能:对图片进行上下左右以及中心裁剪,然后全部翻转(水平或者垂直),获得10张图片,返回一个4D-tensor。
参数:
size- (sequence or int),若为sequence,则为(h,w),若为int,则(size,size)
vertical_flip (bool) - 是否垂直翻转,默认为flase,即默认为水平翻转

2、翻转和旋转——Flip and Rotation

(1)依概率p水平翻转:transforms.RandomHorizontalFlip

class torchvision.transforms.RandomHorizontalFlip(p=0.5)

功能:依据概率p对PIL图片进行水平翻转
参数:
p- 概率,默认值为0.5

(2)依概率p垂直翻转:transforms.RandomVerticalFlip

class torchvision.transforms.RandomVerticalFlip(p=0.5)

功能:依据概率p对PIL图片进行垂直翻转
参数:
p- 概率,默认值为0.5

(3)随机旋转:transforms.RandomRotation

class torchvision.transforms.RandomRotation(degrees, resample=False, expand=False, center=None)

功能:依degrees随机旋转一定角度
参数:
degress- (sequence or float or int) ,若为单个数,如 30,则表示在(-30,+30)之间随机旋转;若为sequence,如(30,60),则表示在30-60度之间随机旋转
resample- 重采样方法选择,可选 PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC,默认为最近邻
expand- ?
center- 可选为中心旋转还是左上角旋转

3、图像变换

(1)重置大小:transforms.Resize

class torchvision.transforms.Resize(size, interpolation=2)

功能:重置图像分辨率
参数:
size- If size is an int, if height > width, then image will be rescaled to (size * height / width, size),所以建议size设定为h*w
interpolation- 插值方法选择,默认为PIL.Image.BILINEAR

(2)转为tensor:transforms.ToTensor

class torchvision.transforms.ToTensor

功能:将PIL Image或者 ndarray 转换为tensor,并且归一化至[0-1]
注意事项:归一化至[0-1]是直接除以255,若自己的ndarray数据尺度有变化,则需要自行修改。

(3)标准化:transforms.Normalize

class torchvision.transforms.Normalize(mean, std) 

功能:对数据按通道进行标准化,即先减均值,再除以标准差,注意是 chw

(4)填充:transforms.Pad

class torchvision.transforms.Pad(padding, fill=0, padding_mode=‘constant’) 

功能:对图像进行填充
参数:
padding-(sequence or int, optional),此参数是设置填充多少个pixel。 当为int时,图像上下左右均填充int个,例如padding=4,则上下左右均填充4个pixel,若为3232,则会变成4040。 当为sequence时,若有2个数,则第一个数表示左右扩充多少,第二个数表示上下的。当有4个数时,则为左,上,右,下。
fill- (int or tuple) 填充的值是什么(仅当填充模式为constant时有用)。int时,各通道均填充该值,当长度为3的tuple时,表示RGB通道需要填充的值。
padding_mode- 填充模式,这里提供了4种填充模式,1.constant,常量。2.edge
按照图片边缘的像素值来填充。
3.reflect,?
4. symmetric,?

(5)修改亮度、对比度和饱和度:transforms.ColorJitter

class torchvision.transforms.ColorJitter(brightness=0, contrast=0, saturation=0, hue=0) 

功能:修改修改亮度、对比度和饱和度

(6)转灰度图:transforms.Grayscale

class torchvision.transforms.Grayscale(num_output_channels=1)

功能:将图片转换为灰度图
参数:
num_output_channels- (int) ,当为1时,正常的灰度图,当为3时, 3 channel with r == g == b

(7)线性变换:transforms.LinearTransformation()

class torchvision.transforms.LinearTransformation(transformation_matrix) 

功能:对矩阵做线性变化,可用于白化处理! whitening: zero-center the data, compute the data
covariance matrix 参数:
transformation_matrix (Tensor) – tensor [D x D], D = C x H x W

(8)仿射变换:transforms.RandomAffine

class torchvision.transforms.RandomAffine(degrees, translate=None, scale=None, shear=None, resample=False, fillcolor=0)

功能:仿射变换

(9)依概率p转为灰度图:transforms.RandomGrayscale

class torchvision.transforms.RandomGrayscale(p=0.1) 

功能:依概率p将图片转换为灰度图,若通道数为3,则3 channel with r == g == b

(10)将数据转换为PILImage:transforms.ToPILImage

class torchvision.transforms.ToPILImage(mode=None) 

功能:将tensor 或者 ndarray的数据转换为 PIL Image 类型数据
参数:
mode- 为None时,为1通道,mode=3通道默认转换为RGB,4通道默认转换为RGBA

(11)transforms.Lambda

Apply a user-defined lambda as a transform.
暂不了解,待补充。

4、transforms 的连续操作

torchvision.transforms.Compose([ ts,ts,ts... ])

ts 为 transforms 操作。
使用 transforms.Compose将一系列的 transforms 操作连接起来。

trans = transforms.Compose((transforms.CenterCrop(300),transforms.RandomRotation(30),
                   transforms.ToTensor(),transforms.Normalize(mean=(0.1,0.2,0.3),std=(1,1,1)),
                   transforms.ToPILImage(mode="RGB")))
trans(im)
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值