Python PIL库图像处理实战:从基础操作到高级合成

橘子海
橘子海
发布时间:2026-10-11 | 3人浏览过
原创

PIL(Pillow)是Python中广泛使用的图像处理库,为图像识别与计算机视觉应用奠定基础。本文基于Python环境,系统梳理PIL核心模块Image的常用方法,包括图像读取、几何变换、多图像合成、像素数据处理及滤波操作,并提供可直接运行的代码示例。

图像基础操作与几何变换

处理图像的第一步通常是读取与展示。PIL通过Image.open()加载文件,返回Image对象。常见的几何变换包括旋转与缩放。

旋转与显示

使用rotate()方法可对图像进行角度旋转,随后调用show()调用系统默认图片查看器展示结果。以下代码演示读取图片并旋转45度:

# -*- coding:utf-8 -*-
from PIL import Image
im = Image.open('test.bmp') # 读取图片
im.rotate(45).show() # 将图片旋转,并用系统自带的图片工具显示图片

缩略图生成

批量处理图片时,生成缩略图是常见需求。PIL提供thumbnail()方法,它按长边等比例缩放,不改变图像宽高比。注意,thumbnail()直接修改原Image对象,若需保存,需调用save()。

# -*- coding:utf-8 -*-
from PIL import Image
import glob,os

size = 128,128

for infile in glob.glob("*.jpg"): # glob的作用是文件搜索,返回的是一个列表
  file,ext = os.path.splitext(infile) # 将文件的文件名和拓展名分开,用于之后的保存重命名
  im = Image.open(infile)
  im.thumbnail(size,Image.ANTIALIAS) # 等比例缩放
  im.save(file+".thumbnail","JPEG")
  #im.show() # 显示缩略图
  #print im.size,im.mode

图像合成技术

将多张图像合并是视觉处理的核心。PIL提供了三种合成方式,但需注意输入图像的mode(色彩模式)和size(尺寸)必须一致,否则需先通过convert()或resize()调整。

Alpha通道合成

alpha_composite(im1, im2)用于将im2合成到im1上,要求两者均为RGBA模式。若背景不透明,合成结果可能仅显示前景图。

混合与遮罩合成

blend(im1, im2, alpha)通过透明度alpha(0.0-1.0)线性混合两图。composite(im1, im2, mask)则利用mask图像控制合成区域,mask的mode可为“1”、“L”或“RGBA”,且尺寸需与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.5)
newim2.show()

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

像素级处理与数组转换

PIL支持对图像像素进行函数映射,并可与NumPy数组互转,便于算法集成。

图像评估(Eval)

Image.eval(image, function)对图像每个像素应用指定函数。例如,将像素值乘以2:

# -*- coding:utf-8 -*-
from PIL import Image
im = Image.open("test.png")

imnew = Image.eval(im,lambda i:i*2) # 将原图片的像素点,都乘2,返回的是一个Image对象
#print imnew.mode
imnew.show()
im.show()

创建新图像

Image.new(mode, size, color)可创建指定模式和大小的新图像。mode支持“L”(灰度)、“RGB”或“RGBA”,size为(width, height)元组,color需与mode对应。

# -*- coding:utf-8 -*-
from PIL import Image
# 创建图像
# 创建一个灰度图像

newL = Image.new("L",(28,28),255)
newL.show()

# 创建一个RGb图像
newrgb = Image.new("RGB",(28,28),(20,200,45))
newrgb.show()

newrgba = Image.new("RGBA",(28,28),(20,200,45,255))
newrgba.show()
print "The frist image:",newL.size,newL.mode
print "The second image:",newrgb.size,newrgb.mode
print "The third image:",newrgba.size,newrgba.mode

数组与图像互转

Image.fromarray(obj)将NumPy数组转换为Image对象。若未指定mode,PIL会自动推断。以下示例演示将RGB图像转换为灰度数组,并通过两种方法(均值法与亮度公式法)重构灰度图像:

# -*- coding:utf-8 -*-
from PIL import Image
import numpy as np
a = Image.open("fromimg.png")
a.show()
b = a.resize((28,28))
datab = list(b.getdata())
#print type(datab)
obj1 = []
obj2 = []
for i in range(len(datab)):
  obj1.append([sum(datab[i])/3]) # 灰度化方法1:RGB三个分量的均值
  obj2.append([0.3*datab[i][0]+0.59*datab[i][1]+0.11*datab[i][2]])
  #灰度化方法2:根据亮度与RGB三个分量的对应关系:Y=0.3*R+0.59*G+0.11*B

obj1 = np.array(obj1).reshape((28,28))
obj2 = np.array(obj2).reshape((28,28))
print obj1
print obj2

arrayimg1 = Image.fromarray(obj1)
arrayimg2 = Image.fromarray(obj2)
arrayimg1.show()
arrayimg2.show()

图像转换、复制与滤波

模式转换与复制

convert(mode)用于转换图像色彩模式,如将RGB转为灰度“L”。copy()创建图像的深拷贝,修改副本不影响原图。

# -*- coding:utf-8 -*-
from PIL import Image
img = Image.open("test.png")
# 灰度化:将RGB/RGBA -> L
img = img.convert("L")
img.show()
# -*- coding:utf-8 -*-
from PIL import Image
img = Image.open("test.png")
# 灰度化:将RGB/RGBA -> L
img = img.convert("L")
#img.show()

# ------ copy()----------
img1 = img.copy()
img1.show()

滤波处理

filter(filter)应用滤波器,参数需来自ImageFilter模块。PIL内置多种滤波器,如中值滤波(MedianFilter)、边缘增强、浮雕等。注意,部分滤波器可能改变图像视觉效果,需根据需求选择。

# -*- coding:utf-8 -*-
from PIL import Image
from PIL import ImageFilter

# BLUR - 模糊处理
# CONTOUR - 轮廓处理
# DETAIL - 增强
# EDGE_ENHANCE - 将图像的边缘描绘得更清楚
# EDGE_ENHANCE_NORE - 程度比EDGE_ENHANCE更强
# EMBOSS - 产生浮雕效果
# SMOOTH - 效果与EDGE_ENHANCE相反,将轮廓柔和
# SMOOTH_MORE - 更柔和
# SHARPEN - 效果有点像DETAIL
testimg = Image.open("filter1.png")
testimg.show()
filterimg = testimg.filter(ImageFilter.MedianFilter)
filterimg.show()

图像信息提取与像素操作

PIL提供多种方法获取图像元数据与像素值,便于分析与调试。

信息获取方法

  • getbands():返回通道元组(如“RGB”)。
  • getbbox():返回非零像素的边界框(4元素元组)。
  • getcolors():返回颜色列表,包含像素数量与颜色值。
  • getdata():返回所有像素值的序列,需转为列表查看。
  • getextrema():返回各通道像素的最小/最大值。
  • getpixel((x, y)):获取指定坐标像素值。
  • histogram():返回像素直方图。
# -*- coding:utf-8 -*-
from PIL import Image
img1 = Image.open("test.png")
img1.show()

# getbands() - 显示该图像的所有通道,返回一个tuple
bands = img1.getbands()
print bands

# getbbox() - 返回一个像素坐标,4个元素的tuple
bboxs = img1.getbbox()
print bboxs

# getcolors() - 返回像素信息,是一个含有元素的列表[(该种像素的数量,(该种像素)),(...),...]
colors = img1.getcolors()
print colors

# getdata() - 返回图片所有的像素值,要使用list()才能显示出具体数值
#data = list(img1.getdata())
#print data

# getextrema() - 获取图像中每个通道的像素最小和最大值,是一个tuple类型
extremas = img1.getextrema()
print extremas

# getpixel() - 获取该坐标
pixels = img1.getpixel((87,180))
print pixels

# histogram() - 返回图片的像素直方图
print(img1.histogram())

粘贴与数据写入

paste(im, box)将图像im粘贴到原图指定位置(box为坐标元组)。要求两图mode和size一致,否则需预处理。putdata(data)将像素序列直接写入原图,无返回值。

# -*- coding:utf-8 -*-
from PIL import Image
rawimg = Image.open("qqtou.png")
print rawimg.size

im = Image.open("number.png")
print im.size

# rawimg的size和im的size要相同,不然不能匹配
# paste(用来粘贴的图片,(位置坐标)),可以通过设置位置坐标来确定粘贴图片的位置
# 该方法没有返回值,直接作用于原图片
rawimg.paste(im,(75,-90))
rawimg.show()
# -*- coding:utf-8 -*-
from PIL import Image

img = Image.open("qqtou.png")
img = img.convert("L")
img.show()

imgdata = list(img.getdata())
print imgdata

addlist = []
for i in range(len(imgdata)):
  if imgdata[i]>250:
    addlist.append(imgdata[i]-100)
  else:
    addlist.append(imgdata[i])


# putdata - 将一个序列添加进原图像,没有返回值,直接作用在原图像中
img.putdata(addlist)
img.show()

以上就是基于Python PIL库进行图像处理的详细内容,涵盖了从基础读取到高级合成的多种操作。更多关于PIL库图像增强、格式转换及与其他AI框架集成的资料,请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表