【python】PIL(上)

转载+整理:python计算机视觉1:基本操作与直方图


PIL 模块全称为 Python Imaging Library,是python中一个免费的图像处理模块。

1 打开图像 open()

PIL模块常用到它的Image类,打开图像首先要导 Image类 from PIL import Image, 然后调用 Image 的 open 方法。

from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg')
print(image)
image

output

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=555x297 at 0x1F9D56294A8>

在这里插入图片描述
哈哈哈,图片中间是我(上半身是我)

2 图像的保存及格式转换 save()

图像保存用的是Image对象的save()方法,传入的参数为保存图像文件的名字。
当传入不同的扩展名时,它会根据扩展名自动转换图像的格式。

from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg') # 打开 png 图像文件
image.save("C://Users/13663//Desktop//1.png") # 保存图像,并转换成png格式

桌面上出现了 1.png 图片
在这里插入图片描述

3 转化成灰度图像 convert()

from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg') 
image_gray = image.convert('L')
print(image)
print(image_gray)
image_gray

output

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=555x297 at 0x1F9D56CE9B0>
<PIL.Image.Image image mode=L size=555x297 at 0x1F9D29332B0>

在这里插入图片描述

4 Image对象与图像矩阵相互转化

4.1 Image对象转化成图片矩阵 numpy.array()

Image对象转化成图像矩阵只要将Image对象作为numpy.array()参数即可。

import numpy as np
from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg') 
image_array=np.array(image)
print(image_array.shape)
print(image_array)

output

(297, 555, 3)
[[[ 76  75  71]
  [ 77  76  72]
  [ 78  77  73]
  ..., 
  [185 138 108]
  [187 138 108]
  [187 138 106]]
  
 [[ 91  96  92]
  [ 89  94  90]
  [ 89  94  90]
  ..., 
  [ 79  78  74]
  [ 79  78  74]
  [ 79  78  74]]]

4.2 图像矩阵转化为Image对象 fromarray()

图像矩阵转化成Image对象通过Image模块的fromarray()方法。

import numpy as np
from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg') 
image_array1 = np.array(image)
image_array2 = np.array(image.convert('L'))
image_array2 = 255 - image_array2 # 黑变白白变黑

image1 = Image.fromarray(image_array1)
image2 = Image.fromarray(image_array2)
print(image2)
print(image1)

output

<PIL.Image.Image image mode=L size=555x297 at 0x1F9D5B7C940>
<PIL.Image.Image image mode=RGB size=555x297 at 0x1F9D5B7C4E0>
image1

在这里插入图片描述

image2

在这里插入图片描述

5 图像的显示 matplotlib

更多关于matplotlib的介绍可以参考【python】matplotlib

from PIL import Image            
import matplotlib.pyplot as plt
import matplotlib.cm as cm         
image = Image.open("/root/userfolder/Experiment/PIL/1.jpg") # 打开图像
image_gray = image.convert("L") # 转化成灰度图像

plt.subplot(2,1,1)
plt.imshow(image)
plt.axis("off") # 去掉座标轴

plt.subplot(2,1,2)
plt.imshow(image_gray)
plt.axis("off") # 去掉座标轴
plt.show() # 显示图像 

在这里插入图片描述
在本地写 plt.imshow(image_gray) 会报错 AttributeError: 'numpy.ndarray' object has no attribute 'mask',应该是版本问题,上面的结果是在 ubuntu 系统上运行的。
不过可以把 Image 对象转化为 array,然后再 plot

from PIL import Image
import matplotlib.pylab as plt
image = Image.open('C://Users/13663//Desktop/1.jpg') 
image_gray = image.convert('L')
image_gray_array = np.array(image_gray)
print(image_gray_array.shape)
plt.imshow(image_gray_array)# 绘制图像image
plt.axis('off')
plt.show()

output

(297, 555)

在这里插入图片描述
……颜色这么诡异,说好的,不是灰度图吗?你个糟老头坏得很!还好小老弟有过一些 matplotlib 经验!应该是 cmap 的原因!Let’s have a try.

from PIL import Image
import matplotlib.pylab as plt
image = Image.open('C://Users/13663//Desktop/1.jpg') 
image_gray = image.convert('L')
image_gray_array = np.array(image_gray)
plt.imshow(image_gray_array,cmap='gray')# 绘制图像image
plt.axis('off')
plt.show()

在这里插入图片描述
OK,说到 cmap,就不得不说……两开花……哈哈哈哈。感受下 cmap 的魅力
在这里插入图片描述
图片来源:matplotlib的cmap(★★★)
更全面的cmap请查看:cmap 介绍(★★★★★)
我们也来 DIY 一些

from PIL import Image
import matplotlib.pylab as plt
image = Image.open('C://Users/13663//Desktop/1.jpg') 
image_gray = image.convert('L')
image_gray_array = np.array(image_gray)
print(image_gray_array.shape)
plt.imshow(image_gray_array,cmap=plt.get_cmap('hot'))# 绘制图像image
plt.axis('off')
plt.subplot(2,2,2)
plt.imshow(image_gray_array,cmap=plt.get_cmap('afmhot'))# 绘制图像image
plt.axis('off')
plt.subplot(2,2,3)
plt.imshow(image_gray_array,cmap=plt.get_cmap('PuBuGn_r'))# 绘制图像image
plt.axis('off')
plt.subplot(2,2,4)
plt.imshow(image_gray_array,cmap=plt.get_cmap('PuBuGn'))# 绘制图像image
plt.axis('off')
plt.show()

在这里插入图片描述

6 创建缩略图 thumbnail()

创建图像缩略图可以通过Image的 thumbnail() 方法,参数传入一个元组,指明缩略图的大小,如thumbnail((128,128))

from PIL import Image
import matplotlib.pylab as plt
image = Image.open('C://Users/13663//Desktop/1.jpg') 
print(image)
# 缩略图
image_thumbnail = image.thumbnail((555*0.5,297*0.5))
image.save("C://Users/13663//Desktop/thumbnail.jpg") 
# 看看大小
image_thumbnail = Image.open("C://Users/13663//Desktop/thumbnail.jpg") 
print(image_thumbnail)

output

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=555x297 at 0x1F9D99E9E80>
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=277x148 at 0x1F9D8139710>

在这里插入图片描述
可以看出,size 变了,视觉上来感受一下
在这里插入图片描述

7 复制和粘贴区域

7.1 复制区域 crop()

复制区域是指截取图像中的一部分,并将这一部分作为一个新的Image对象。 复制区域的方法为 crop(),参数为一个含4个元素的元组,用来指定截取区域的左上角点和右下角点。

from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg')  # 打开图像
box = (0,0,300,297) # 截取区域,(left, upper, right, lower),左上,右下
image_crop = image.crop(box) # 按指定截取区域对图像进行截取复制
image_crop.save("C://Users/13663//Desktop/image_crop.jpg") # 保存

image_crop = Image.open("C://Users/13663//Desktop/image_crop.jpg")

plt.subplot(2,1,1)
plt.imshow(image)# 绘制图像image
plt.axis('off')

plt.subplot(2,1,2)
plt.imshow(image_crop)
plt.axis('off')
plt.show()

在这里插入图片描述

7.2 粘贴区域 paste()

粘贴区域是指在指定图像中放入另一个图像,其方法为paste()。该方法有两个参数,第一个参数为需要粘贴进去的图像,第二个参数为粘贴区域。

from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg')

plt.subplot(2,1,1)
plt.imshow(image)# 绘制图像image
plt.axis('off')

box = (0,0,200,297)        # 先截取一部分
image_crop = image.crop(box)    

# 为了看到粘贴效果,现将截取部分转180度
image_crop = image_crop.transpose(Image.ROTATE_180) # 转180度
image.paste(image_crop,box) # 将转180度后的图像粘贴到原图像

image.save('C://Users/13663//Desktop/image_paste.jpg')
image_paste = Image.open("C://Users/13663//Desktop/image_paste.jpg")
plt.subplot(2,1,2)
plt.imshow(image_paste)# 绘制图像image
plt.axis('off')
plt.show()

在这里插入图片描述

8 图像的尺寸调整 resize()

尺寸调整方法为resize(),参数为一元组,指定调整后的大小,如resize((200,200))。

from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg')
image_resize = image.resize((200,200)) # 尺寸调整
image_resize.save("C://Users/13663//Desktop/image_resize.jpg")

image_resize = Image.open("C://Users/13663//Desktop/image_resize.jpg")
print(image)
print(image_resize)
plt.subplot(2,1,1)
plt.imshow(image)# 绘制图像image
plt.axis('off')
plt.subplot(2,1,2)
plt.imshow(image_resize)# 绘制图像image
plt.axis('off')
plt.show()

output

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=555x297 at 0x1F9D81AE978>
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=200x200 at 0x1F9D95434A8>

在这里插入图片描述

9 图片的旋转 rotate

图像旋转的方法为rotate(),参数为旋转角度(数值,单位为度),逆时针方向,如rotate(45)`

from PIL import Image
image = Image.open('C://Users/13663//Desktop/1.jpg')
image_rotate = image.rotate(45) # 图像旋转
# image.transpose()也可以旋转图像,但只能旋转90度的整数倍
# 参数为 Image.ROTATE_90 旋转90度
# 180度,270度可类推
image_rotate.save("C://Users/13663//Desktop/image_rotate.jpg")
image_resize = Image.open("C://Users/13663//Desktop/image_rotate.jpg")
print(image)
print(image_resize)
plt.subplot(2,1,1)
plt.imshow(image)# 绘制图像image
plt.axis('off')
plt.subplot(2,1,2)
plt.imshow(image_resize)# 绘制图像image
plt.axis('off')
plt.show()

output

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=555x297 at 0x1F9D805A978>
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=555x297 at 0x1F9D81AEB38>

在这里插入图片描述

10 图像直方图 hist()

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
#打开图像,并转化成灰度图像
image = Image.open('C://Users/13663//Desktop/1.jpg').convert('L')
image_array = np.array(image)
plt.subplot(2,1,1)
plt.imshow(image_array,cmap='gray')
plt.axis("off")
plt.subplot(2,1,2)
plt.hist(image_array.flatten(),256) #flatten可以将矩阵转化成一维序列
plt.show()

在这里插入图片描述

11 灰度变换

对于一张灰度图像,其每个像素点都用一个0-255之间的值表示,0表示黑色,越接近0越黑;255表示白色,越接近255越白。
灰度变换就是通过一个特定的函数,使灰度值从一个值转换成另外一个值。
这里列出3种灰度变换

  1. =255【反相】变换后的灰度值= 255−原灰度值
  2. 100200=(/255)100+100【转换到100-200】变换后的灰度值 =(原灰度值/255)*100+100
  3. =255(/255)2【像素平方】变换后的灰度值 = 255*(原灰度值/255)^2
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm
image = Image.open('C://Users/13663//Desktop/1.jpg').convert("L")
image_array = np.array(image)
x = np.arange(255)
# 反相
plt.subplot(3,2,1)
plt.plot(x,255-x) # 画出变换函数图像
plt.subplot(3,2,2)
plt.imshow(255-image_array,cmap='gray')
plt.axis("off")
# 转换到 100-200
plt.subplot(3,2,3)
plt.plot(x,(x/255.0)*100+100) # 画出变换函数图像
plt.subplot(3,2,4)
plt.imshow( Image.fromarray((image_array/255.0)*100+100),cmap='gray')
plt.axis("off")
# 像素平方
plt.subplot(3,2,5)
plt.plot(x,255*(x/255.0)**2) # 画出变换函数图像
plt.subplot(3,2,6)
plt.imshow(255*(image_array/255.0)**2,cmap='gray')
plt.axis("off")
plt.show()

在这里插入图片描述

12 直方图均衡化

由上面图像的直方图可以看出,一般情况下,图像上某些灰度值较多,有些灰度值较少,直方图均衡化为的是使灰度值较为均衡。
直方图均衡化是利用直方图的累积函数作为灰度变换函数,对图像进行转换。直方图均衡化可以增强图像的对比度。
累积函数和概率论中的累积分布函数类似。例如对于还有5个数的序列[1,2,3,4,5],其累积函数含有5个数,第一个数是1,第二个是1+2=3,……,第五个数是1+2+3+4+5=15,所以其累积函数是[1,3,6,10,15]。
我们把直方图均衡化的过程封装在一个函数里面,函数名字叫做histeq,输入原图像矩阵和直方图分块数,输出均衡化后的图像矩阵和累积函数。

import numpy as np 
from PIL import Image
import matplotlib.pyplot as plt

def histeq(image_array,image_bins=256):

    # 将图像矩阵转化成直方图数据,返回元组(频数,直方图区间座标)
    image_array2,bins = np.histogram(image_array.flatten(),image_bins)

    # 计算直方图的累积函数
    cdf = image_array2.cumsum()

    # 将累积函数转化到区间[0,255]
    cdf = (255.0/cdf[-1])*cdf
    
    # 原图像矩阵利用累积函数进行转化,插值过程
    image2_array = np.interp(image_array.flatten(),bins[:-1],cdf)

    # 返回均衡化后的图像矩阵和累积函数
    return image2_array.reshape(image_array.shape),cdf

image = Image.open("/root/userfolder/Experiment/PIL/1.jpg").convert("L") 
image_array = np.array(image)
plt.subplot(2,2,1)
plt.hist(image_array.flatten(),256)
plt.subplot(2,2,2)
plt.imshow(image_array,cmap='gray')
plt.axis("off")

a = histeq(image_array)  # 利用刚定义的直方图均衡化函数对图像进行均衡化处理
plt.subplot(2,2,3)
plt.hist(a[0].flatten(),256)
plt.subplot(2,2,4)
plt.imshow(a[0],cmap='gray')
plt.axis("off")
plt.show()

在这里插入图片描述


本文主要内容来源于书籍《python计算机视觉编程》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章