Python处理图像-pillow

发布时间 2023-06-04 11:46:53作者: ashuai~

 一、预先知识:

1. 颜色:

美术三原色:红、黄、蓝,它们是不能再分解的基本颜色。

色光三原色:红、绿、蓝,在计算机中,我们可以将红、绿、蓝三种色光以不同的比例叠加来组合成其他的颜色。在计算机系统中,我们通常会将一个颜色表示为一个RGB值或RGBA值(其中的A表示Alpha通道,它决定了透过这个图像的像素,也就是透明度)。

2. 像素:

对于一个由数字序列表示的图像来说,最小的单位就是图像上单一颜色的小方格,这些小方块都有一个明确的位置和被分配的色彩数值,而这些一小方格的颜色和位置决定了该图像最终呈现出来的样子,它们是不可分割的单位,我们通常称之为像素(pixel)。每一个图像都包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。

Pillow是由从著名的Python图像处理库PIL发展出来的一个分支,通过Pillow可以实现图像压缩和图像处理等各种操作

一 安装:

pip install pillow

二、使用

Pillow中最为重要的是Image类,可以通过Image模块的open函数来读取图像并获得Image类型的对象。

1.读取和显示图像

from PIL import Image

# 读取图像获得Image对象
image = Image.open('people1.jpg')
# 通过Image对象的format属性获得图像的格式
print(image.format) # JPEG
# 通过Image对象的size属性获得图像的尺寸
print(image.size)   # (500, 750)
# 通过Image对象的mode属性获取图像的模式
print(image.mode)   # RGB
# 通过Image对象的show方法显示图像
image.show()


"""
format 图像格式
size 图像的 (宽,高) 元组
mode 常见模式,默认 RGB 真彩图像;L 为灰阶图像;CMYK 印刷色彩;RGBA 带透明度的真彩图像;YCbCr 彩色视频格式;LAB L * a * b颜色空间;HSV 等。
show() 方法为使用系统默认图片查看器显示图像,一般用于调试;
"""

从 string 二进制流中读取

import io
from PIL import Image

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

从tar文件中读取

from PIL import TarIO

fp = TarIO.TarIO("Imaging.tar", "Imaging/test/lena.ppm")
im = Image.open(fp)

2. 格式转换并保存图像

import os
from PIL import Image

image_path='python-logo.png' # 图片位置
f, e = os.path.splitext(image_path) # 获取文件名与后缀
outfile = f + ".jpg"   # png 转 jpg
if image_path != outfile:
    try:
        Image.open(image_path).save(outfile) # 修改文件格式
    except IOError:
        print("cannot convert", image_path)

"""
save 函数可以保存图片,有两个参数, 一为文件名,二为文件格式,当未指定文件格式,文件的扩展名就是文件格式。

注:如果你的图片mode是RGBA那么会出现异常,因为 RGBA 意思是红色,绿色,蓝色,Alpha 的色彩空间,Alpha 是指透明度。而 JPG 不支持透明度 ,所以要么丢弃Alpha , 要么保存为.png文件。解决方法将图片格式转换:
Image.open(image_path).convert("RGB").save(outfile) 去掉A 转为RGB
"""

3. 剪裁图像

"""
通过Image对象的crop方法指定剪裁区域剪裁图像
定义box元组,表示图像基于左上角为(0,0)的坐标,box 坐标为 (左,上,右,下)截取左上右下四个坐标
框出的区域
"""
box = (100, 100, 400, 400)
image.crop(box).show()

4. 生成缩略图

# 通过Image对象的thumbnail方法生成指定尺寸的缩略图
image.thumbnail((128, 128))  #(128, 128)未缩略图宽长元组
image.show()

5. 黏贴图像

# paste() 方法粘贴,两个参数,一为粘入的图像,二为粘贴位置(左,上,右,下)元组

# 截取矩形图像
box = (100, 100, 400, 400)
region = im.crop(box)

# 在原图上粘贴子矩形图像
region = region.transpose(Image.ROTATE_180) # 颠倒180度
box = (400, 400, 700, 700)  # 粘贴位置,像素必须吻合,300 * 300
im.paste(region, box)

6. 几何变换

Image 包含调整图像大小 resize() 和旋转 rotate() 的方法。

调整大小并逆时针旋转 45度
out = im.resize((128, 128)) # 重新定义图像宽 高
out = out.rotate(45)

"""
 transpose() 方法。可用于围绕其水平轴或垂直轴翻转图像。
"""

out = im.transpose(Image.FLIP_LEFT_RIGHT) # 水平左右翻转
out = im.transpose(Image.FLIP_TOP_BOTTOM) # 垂直上下翻转
out = im.transpose(Image.ROTATE_90) # 逆时针90度
out = im.transpose(Image.ROTATE_180) # 逆时针180度
out = im.transpose(Image.ROTATE_270) # 逆时针270度

7. 颜色变换

from PIL import Image
im = Image.open("hopper.ppm").convert("L") # 转换为灰阶图像 它支持每种模式转换为"L" 或 "RGB"

8. 滤镜效果

"""
ImageFilter模块包含了诸多预设的滤镜也可以自定义滤镜 Filters 过滤器
ImageFilter 模块有很多预定义的增强过滤器,通过 filter() 方法运用, 对图像进行滤镜处理
"""

image_path = 'people1.jpg'
image = Image.open(image_path)
image.filter(ImageFilter.CONTOUR).show()

9. 像素点处理

"""
point() 方法可用于转换图像的像素值(如对比度),在大多数情况下,可以将函数对象作为参数传递格此方法,它根据函数返回值对每个像素进行处理。
"""
# 每个像素点扩大1.2倍
out = im.point(lambda i: i * 1.2)

10. 高级增强

其他图像增强功能可以使用 ImageEnhance 模块中的类。从图像创建后,可以使用 ImageEnhance 快速调整图片的对比度、亮度、饱和度和清晰度。

"""
ImageEnhance.Contrast(im) 对比度
ImageEnhance.Color(im) 色彩饱和度
ImageEnhance.Brightness(im) 亮度
ImageEnhance.Sharpness(im) 清晰度
"""

image_path = 'people1.jpg'
image = Image.open(image_path)

enh = ImageEnhance.Contrast(image)  # 创建调整对比度对象
image2 = enh.enhance(1.3)  # 返回一个图片对象
# image2.show()

brg = ImageEnhance.Brightness(image2)
brg.enhance(1.2).show()

三、使用Pillow绘图

"""
Pillow中有一个名为ImageDraw的模块,该模块的Draw函数会返回一个ImageDraw对象,
通过ImageDraw对象的arc、line、rectangle、ellipse、polygon等方法,
可以在图像上绘制出圆弧、线条、矩形、椭圆、多边形等形状,也可以通过该对象的text方法在图像上添加文字。
"""

import random

from PIL import Image, ImageDraw, ImageFont


def random_color():
    """生成随机颜色"""
    red = random.randint(0, 255)
    green = random.randint(0, 255)
    blue = random.randint(0, 255)
    return red, green, blue


width, height = 800, 600
# 创建一个800*600的图像,背景色为白色
image = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
# 创建一个ImageDraw对象
drawer = ImageDraw.Draw(image)
# 通过指定字体和大小获得ImageFont对象
# font = ImageFont.truetype('Kongxin.ttf', 32)
# 通过ImageDraw对象的text方法绘制文字
drawer.text((300, 50), 'Hello, world!', fill=(255, 0, 0))  # , font=font)
# 通过ImageDraw对象的line方法绘制两条对角直线
drawer.line((0, 0, width, height), fill=(0, 0, 255), width=2)
drawer.line((width, 0, 0, height), fill=(0, 0, 255), width=2)
xy = width // 2 - 60, height // 2 - 60, width // 2 + 60, height // 2 + 60
# 通过ImageDraw对象的rectangle方法绘制矩形
drawer.rectangle(xy, outline=(255, 0, 0), width=2)
# 通过ImageDraw对象的ellipse方法绘制椭圆
for i in range(4):
    left, top, right, bottom = 150 + i * 120, 220, 310 + i * 120, 380
    drawer.ellipse((left, top, right, bottom), outline=random_color(), width=8)
# 显示图像
image.show()
# 保存图像
image.save('result.png')

四、参考:

知乎 木头人 Python 图像处理 Pillow 库 基础篇Python 图像处理 Pillow 库 基础篇 - 知乎 (zhihu.com)

GitHub:javkfrued大神的python语言基础课

Python-Core-50-Courses/第28课:用Python处理图像.md at master · jackfrued/Python-Core-50-Courses (github.com)