PIL:Python图像处理类库
- 读取、灰度、保存:
from PIL import Image
# 打开一个图像,注意是当前路径:
im = Image.open('1.png')
# 灰度化处理
im = Image.open('1.png').convert('L')
# 保存灰度图像:
im.save('2.png')
我们导入
Image
模块,在python模块学习中我们会知道,这样做会得到名Image
的对象,这个模块对象包含了im这样的常量,以及一些其它的方法。我们如果直接访问 im,不加Image
这个前缀会发生什么情况呢?程序抛出了一个名为“NameError”的错误。这个时候我们可以用from这个方法来实现可以直接用im这个方法。from会把变量名复制到另一个作用域,所以它就可以直接在脚本中使用复制后的变量名,而不用通过模块。
- 批量图片格式转换
from PIL import Image
import os
def get_imlist(path):#获取文件名列表
return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.png')]#读取png
filelist=get_imlist('C:/Users/Huawei/Desktop/EXP2/image')#建立一个列表对象
#print(filelist)
for infile in filelist:
outfile = os.path.splitext(infile)[0] + ".jpg"#保存为jpg
if infile != outfile:
try:
Image.open(infile).save(outfile)
except IOError:
print("cannot convert", infile)
注意文件路径的分隔符是/
只有字符串是双引号,文件名和文件路径都是单引号
- 创建缩略图
from PIL import Image
# 打开一个当前路径的图像:
im = Image.open('1.png')
im.thumbnail((128,128))
# 保存缩略图:
im.save('3.png')
- 复制粘贴
from PIL import Image
# 打开一个当前路径的图像:
im = Image.open('1.png')
# 裁剪
box = (100,100,400,400)
region = im.crop(box)
# 旋转180度
region = region.transpose(Image.ROTATE_180)
# 粘贴
im.paste(region,box)
# 保存:
im.save('4.png')
- 调整尺寸及旋转
from PIL import Image
# 打开一个当前路径的图像:
im = Image.open('1.png')
# 调整尺寸
im = im.resize((128,128))
# 旋转
im = im.rotate(45)
# 保存:
im.save('5.png')
Matplotlib
绘制图像、点和线
from PIL import Image
from pylab import *
im = Image.open('1.png')
# 绘制图像
imshow(im)#没有imshow(),show()将无法显示原图
axis('off')#不显示坐标轴
# x是横坐标,y是纵坐标:(100,200)(100,500)...
x = [100,100,400,400]
y = [200,500,600,800]
#绘制点或线
plot(x,y) # 默认为蓝色实线
plot(x,y,'r*') # 红色星状标记
plot(x,y,'go-') # 带有圆圈标记的绿线
plot(x,y,'ks:') # 带有正方形标记的黑色虚线
# 绘制连接前两个点的线
plot(x[:2],y[:2])#what?
# 添加标题
title('Plotting: "1.png"')
# 原图及绘制的点、线输出到屏幕
show()
表1-1:用PyLab
库绘图的基本颜色格式命令
颜色 |
|
---|---|
| 蓝色 |
| 绿色 |
| 红色 |
| 青色 |
| 品红 |
| 黄色 |
| 黑色 |
| 白色 |
表1-2:用PyLab
库绘图的基本线型格式命令
线型 |
|
---|---|
| 实线 |
| 虚线 |
| 点线 |
表1-3:用PyLab
库绘图的基本绘制标记格式命令
标记 |
|
---|---|
| 点 |
| 圆圈 |
| 正方形 |
| 星形 |
| 加号 |
| 叉号 |
图像轮廓和直方图
from PIL import Image
from pylab import *
# 读取图像到数组中,一定要读进数组,array(),否则无法绘制直方图(flatten)
im = array(Image.open('1.png').convert('L'))
# 新建一个图像
figure()
# 不使用颜色信息,灰度化
gray()
# 在原点的左上角显示轮廓图像
contour(im, origin='image')
# 坐标
axis('equal')
axis('off')
# 新建一个图像
figure()
# 图像的直方图可以使用 hist() 函数绘制
hist(im.flatten(),128)
show()
hist()
只接受一维数组作为输入,所以我们在绘制图像直方图之前,必须先对图像进行压平处理。
flatten()
方法将任意数组按照行优先准则转换成一维数组。
交互式标注
from PIL import Image
from pylab import *
im = Image.open('1.png')
#显示图片到屏幕
imshow(im)
print('Please click 3 points')
x = ginput(3)
print('you clicked:',x)
show()#这个show()貌似没有用
图像数组表示
当载入图像时,我们通过调用
array()
方法将图像转换成NumPy
的数组对象
from PIL import Image
from pylab import *
im = array(Image.open('1.png'))
print (im.shape, im.dtype)
im = array(Image.open('1.png').convert('L'),'f')
print (im.shape, im.dtype)
每行的第一个元组表示图像数组的大小(行、列、颜色通道),紧接着的字符串表示数组元素的数据类型。因为图像通常被编码成无符号八位整数(uint8),所以在第一种情况下,载入图像并将其转换到数组中,数组的数据类型为“uint8”。在第二种情况下,对图像进行灰度化处理,并且在创建数组时使用额外的参数“f”;该参数将数据类型转换为浮点型。
多个数组元素可以使用数组切片方式访问。切片方式返回的是以指定间隔下标访问该数组的元素值。下面是有关灰度图像的一些例子:
im[i,:] = im[j,:] # 将第 j 行的数值赋值给第 i 行
im[:,i] = 100 # 将第 i 列的所有数值设为100
im[:100,:50].sum() # 计算前100 行、前 50 列所有数值的和
im[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)
im[i].mean() # 第 i 行所有数值的平均值
im[:,-1] # 最后一列
im[-2,:] (or im[-2]) # 倒数第二行
灰度变换
将图像读入
NumPy
数组对象后,我们可以对它们执行任意数学操作。
from PIL import Image
from pylab import *#imshow()show()
from numpy import *
im = array(Image.open('1.png').convert('L'))
im2 = 255 - im # 对图像进行反相处理
im3 = (100.0/255) * im + 100 # 将图像像素值变换到100...200 区间
im4 = 255.0 * (im/255.0)**2 # 对图像像素值求平方后得到的图像
imshow(im)
show()
imshow(im2)
show()
imshow(im3)
show()
imshow(im4)
show()
print (int(im.min()), int(im.max()))查看最小/最大 灰度值
直方图均衡化
from PIL import Image
from pylab import *
def histeq(im,nbr_bins=256):
""" 对一幅灰度图像进行直方图均衡化"""
# 计算图像的直方图
imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
cdf = imhist.cumsum() # cumulative distribution function
cdf = 255 * cdf / cdf[-1] # 归一化
# 使用累积分布函数的线性插值,计算新的像素值
im2 = interp(im.flatten(),bins[:-1],cdf)
return im2.reshape(im.shape), cdf
im = array(Image.open('1.png').convert('L')) # 打开图像,并转成灰度图像
im2, cdf = histeq(im)
figure()
subplot(2, 2, 1)
axis('off')
gray()
title(u'Origin')
imshow(im)
subplot(2, 2, 2)
axis('off')
title(u'Processed')
imshow(im2)
subplot(2, 2, 3)
axis('off')
title(u'Origin Graph')
hist(im.flatten(), 128, normed=True)
subplot(2, 2, 4)
axis('off')
title(u'Processed Graph')
hist(im2.flatten(), 128, normed=True)
show()
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
title(u'原始图像', fontproperties=font)
图像平均
from PIL import Image
from pylab import *#imshow()show()
from numpy import *
import os
def get_imlist(path):#获取文件名列表
return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.png')]#读取png
def compute_average(imlist):
""" 计算图像列表的平均图像"""
# 打开第一幅图像,将其存储在浮点型数组中
averageim = array(Image.open(imlist[0]), 'f')
for imname in imlist[1:]:
try:
averageim += array(Image.open(imname))
except:
print (imname + '...skipped')
averageim /= len(imlist)
# 返回uint8 类型的平均图像
return array(averageim, 'uint8')
filelist = get_imlist('C:/Users/Huawei/Desktop/EXP2/image')
avg = compute_average(filelist)
for impath in filelist:
im1 = array(Image.open(impath))
subplot(2, 2, filelist.index(impath)+1)
imshow(im1)
imNum=str(filelist.index(impath)+1)
title(u'Origin'+imNum)
axis('off')
subplot(2, 2, 4)
imshow(avg)
title(u'Processed')
axis('off')
show()
有Warning未解决
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步