Pillow图像处理

opencv处理图像见另一篇文章:https://blog.csdn.net/weixin_43435675/article/details/88144121
在这里插入图片描述

0.载入相关函式库

# 把一些警告的讯息暂时关掉
import warnings
warnings.filterwarnings('ignore')
# Utilities相关函式库
import os
# 图像处理/展现的相关函式库
import matplotlib.pyplot as plt

# 专案的根目录路径
ROOT_DIR = os.getcwd()

# 训练/验证用的资料目录
DATA_PATH = os.path.join(ROOT_DIR, "data")

# 测试用图像
TEST_IMAGE = os.path.join(DATA_PATH, "hugh_jackman.jpg")

1.图像物件 Image

Python Imaging Library中的一个关键类别是Image, 它定义在Image模组中

from PIL import Image
# 载入图像档
image = Image.open(TEST_IMAGE)

# 储存图像档并转换格式(jpg -> png)
image.save(os.path.join(DATA_PATH, "new_image.png"))

plt.imshow(image); plt.show()

在这里插入图片描述
Pillow从文件扩展名中决定使用的文件存储格式。

2.调整图像大小

要调整图像大小,可以调用resize()方法,传递一个两个整数的tuple参数,表示调整大小的图像的宽度和高度。该函数不会修改使用的图像,而是返回具新维度的另个图像。

# 载入图像档
image = Image.open(TEST_IMAGE)

# 调整大小
new_image = image.resize((400, 400))

print('原本图像大小: ', image.size)
print('新的图像大小: ', new_image.size)

plt.imshow(new_image); plt.show()

在这里插入图片描述

3.图像缩图 (thumpnail)

如果要调整图像大小并保持其长宽的比例,则应该使用thumbnail()函数来调整它们的大小。这还需要表示缩略图的最大宽度和最大高度的两个整数元组参数。

# 载入图像档
image = Image.open(TEST_IMAGE)

# 产生缩图并保持长宽比
image.thumbnail((400, 400))

print('新的缩图大小: ', image.size)

plt.imshow(image); plt.show()

在这里插入图片描述
以上将产生一个图像大小为(400, 227),它保持原始图像的宽高比(755, 429)。正如你可以看到的,这样的作法会让缩放的结果比较正常。ps.请注意在PIL的Image.size回传的是 (width, height) 与一般使用OpenCV所回传的 (height, width, channels) 的资讯不太一样

4.图像裁剪 (cropping)

裁切图像时,图像内的矩形区域将被选中并保留,而区域外的所有其他区域都将被移除。使用Pillow库,用Image类的crop()方法裁剪图像。该方法采用一个边界框(bounding box)定义裁剪区域的位置和大小,并返回一个代表裁剪图像的Image对象。框的坐标是(left, upper, right, lower)或(x1, y1, x2, y2)。

# 载入图像档
image = Image.open(TEST_IMAGE)

# 定义要裁剪的边界框座标
x1 = 200; y1 = 50
x2 = 460; y2 = 320
bbox = (x1, y1, x2, y2)

# 进行裁剪
cropped_image = image.crop(bbox)

plt.imshow(cropped_image); plt.show()

在这里插入图片描述

5.将图像粘贴到另一个图像上

Pillow函式库能够将图像粘贴到另一个图像上。一些使用案例是通过在其图像添加水印来保护公开可用的图像,或是添加公司商标。使用paste()函数完成粘贴的动作。这个动作修改了Image对象,它不像我们目前看到的其他处理函数返回一个新的Image对象。因此,在执行粘贴之前,我们将首先复制原始图像,以便用未修改的图像继续处理其他处理。

# 载入图像档
image = Image.open(TEST_IMAGE)

# 载入浮水印图像档
logo = Image.open(os.path.join(DATA_PATH, "thumbup.png"))

# 修改成合适大小
logo.thumbnail((200, 200))

# 复制图像
image_copy = image.copy()

# 指定要粘贴的左上角座标
position = ((image_copy.width - logo.width), (image_copy.height - logo.height))

# 进行粘贴
image_copy.paste(logo, position)

plt.imshow(image_copy); plt.show()

在这里插入图片描述
为了达到这个目的,你需要把第三个参数传递给paste()函数。这个参数是透明度掩码/遮罩图像物件对象。蒙版是一个图像对象,其中的alpha值是重要的,但其绿色,红色和蓝色值将被忽略。如果给出遮罩,则paste()仅更新由掩码指示的区域。您可以使用1,L或RGBA图像作为遮罩。粘贴RGBA图像并将其用作遮罩将粘贴图像的不透明部分,但不粘贴透明背景。如果您修改粘贴如下所示,您应该有一个透明像素粘贴徽标。

# 载入图像档
image = Image.open(TEST_IMAGE)

# 载入浮水印图像档
logo = Image.open(os.path.join(DATA_PATH, "thumbup.png"))

# 修改成合适大小
logo.thumbnail((200, 200))

# 复制图像
image_copy = image.copy()

# 指定要粘贴的左上角座标
position = ((image_copy.width - logo.width), (image_copy.height - logo.height))

image_copy.paste(logo, position, logo) # <-- 就是这里

plt.imshow(image_copy); plt.show()

在这里插入图片描述

6.图像旋转 (Rotating)

你可以使用rotate()方法逆时钟地旋转图像。这需要一个整数或浮点型参数来表示旋转图像的角度,并返迴旋转图像的新Image对象。

# 载入图像档
image = Image.open(TEST_IMAGE)

# 逆时钟地旋转图像90度
image_rot_90 = image.rotate(90)

plt.imshow(image_rot_90); plt.show()

# 逆时钟地旋转图像180度
image_rot_180 = image.rotate(180)

plt.imshow(image_rot_180); plt.show()

在这里插入图片描述

# 载入图像档
image = Image.open(TEST_IMAGE)

# 逆时钟地旋转图像18度
image_rot_18 = image.rotate(18)

plt.imshow(image_rot_18); plt.show()

在这里插入图片描述
要扩展让旋转图像的尺寸以适应整个图像,可以将第二个参数传递给rotate(),如下所示

# 载入图像档
image = Image.open(TEST_IMAGE)

# 逆时钟地旋转图像18度并让图像扩大来包含新的图像
image_rot_18_expand = image.rotate(18, expand=True)

plt.imshow(image_rot_18_expand); plt.show()

在这里插入图片描述
现在图像的内容将完全可见,并且图像的尺寸将会增加以解决这个问题。

7.图像翻转 (Flipping)

你也可以翻转图像来获得他们的镜像版本。这是用transpose()函数完成的。你可以用以下选项:
PIL.Image.FLIP_LEFT_RIGHT
PIL.Image.FLIP_TOP_BOTTOM
PIL.Image.ROTATE_90
PIL.Image.ROTATE_180
PIL.Image.ROTATE_270
PIL.Image.TRANSPOSE

# 载入图像档
image = Image.open(TEST_IMAGE)

# 左右互换
image_flip = image.transpose(Image.FLIP_LEFT_RIGHT) 

plt.imshow(image_flip); plt.show()

# 上下互换
image_flip = image.transpose(Image.FLIP_TOP_BOTTOM) 

plt.imshow(image_flip); plt.show()

在这里插入图片描述

8.在图像上绘图

使用Pillow函式库,你也可以使用ImageDraw模组来绘製图像。您可以绘制直线,点,椭圆,矩形,弧,二元图,和弦,pieslices,多边形,形状和文本。

from PIL import Image, ImageDraw, ImageFont

# 产生一个有4个颜色channels的空白图像
blank_image = Image.new('RGBA', (400, 300), 'white')

 # 在blank_image图像上绘图
img_draw = ImageDraw.Draw(blank_image)

# 画一个矩形
img_draw.rectangle((70, 50, 270, 200), outline='red', fill='blue')

# 取得字型物件
fnt = ImageFont.truetype('comic.ttf', 40) # 修改你电脑上有的字型

# 放上文字讯息到图像上
img_draw.text((70, 250), 'Hello World', font=fnt, fill='green')

plt.imshow(blank_image); plt.show()

在这里插入图片描述

from PIL import Image, ImageDraw, ImageFont

# 产生一个有4个颜色channels的空白图像
blank_image = Image.new('RGBA', (400, 300), 'white')

img_draw = ImageDraw.Draw(blank_image) # 在blank_image图像上绘图

# 在PIL要可以用rectangle来划一个四方形, 但是无法控制框线的粗细
img_draw.rectangle((70, 50, 270, 200), outline= None, fill='pink')

# 透过画线来画一个四方框的框线并控制粗细
img_draw.line([(70,50),(270,50),(270,200),(70,200),(70,50)], fill='red', width=4)

# 在PIL要画一个可以控制大小的图要透过以下的手法
r = 10 # 设定半径

# 以图的中心点(x,y)来计算框住圆的边界框座标[(x1,y1),(x2,y2)]
img_draw.ellipse((270-r,200-r, 270+r, 200+r), fill='orange') 

# 画一个多边形
img_draw.polygon([(40, 40), (40, 80), (80, 60), (60, 40)], fill='green', outline=None)

plt.imshow(blank_image); plt.show()

在这里插入图片描述

9.颜色变换

Pillow函式库允许你使用convert()方法在不同的像素表示之间转换图像。它支持L(灰度),RGB和CMYK模式之间的转换。
在下面的例子中,我们将图像从RGBA转换为L模式,这将彩色图像转换成灰阶图像。

# 載入圖像檔
image = Image.open(TEST_IMAGE)

# 將彩色轉換成灰階
greyscale_image = image.convert('L') 

# 注意要註明cmat='gray'才能夠正確秀出灰階圖像
plt.imshow(greyscale_image, cmap='gray') 
plt.show()

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43435675/article/details/89430022
今日推荐