【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計算機視覺編程》

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