Python基本圖像操作
使用python進行基本的圖像操作與處理
前言:
與早期計算機視覺領域多數程序都是由 C/C++ 寫就的情形不同。隨着計算機硬件速度越來越快,研究者在考慮選擇實現算法語言的時候會更多地考慮編寫代碼的效率和易用性,而不是像早年那樣把算法的執行效率放在首位。這直接導致近年來越來越多的研究者選擇 Python 來實現算法。
今天在計算機視覺領域,越來越多的研究者使用 Python 開展研究,所以有必要去學習一下十分易用的python在圖像處理領域的使用,這篇博客將會介紹如何使用Python的幾個著名的圖像處理庫完成最基本的圖像操作與處理。
使用PIL進行基本圖像操作
PIL簡介:
PIL(Python Imaging Library Python,圖像處理類庫)提供了通用的圖像處理功能,以及大量有用的基本圖像操作,比如圖像縮放、裁剪、旋轉、顏色轉換等。
PIL讀取與存儲圖像:
利用 PIL 中的函數,我們可以從大多數圖像格式的文件中讀取數據,然後寫入最常見的圖像格式文件中。PIL 中最重要的模塊爲 Image 。
下面這個程序我使用PIL讀取一張jpg圖片將其灰度化之後存爲一個png文件:
# -*- coding: utf-8 -*-
from PIL import Image
import os
#打開圖像得到一個PIL圖像對象
img = Image.open("./source/test.jpg")
#將其轉爲一張灰度圖
img = img.convert('L')
#存儲該張圖片
try:
img.save("test.png")
except IOError:
print "cannot convert"
Test.jpg
Test.png
PIL生成縮略圖:
# -*- coding: utf-8 -*-
from PIL import Image
import os
#打開圖像得到一個PIL圖像對象
img = Image.open("./source/test.jpg")
#創建最長邊爲128的縮略圖
img.thumbnail((128,128))
#存儲該張圖片
try:
img.save("test.png")
except IOError:
print "cannot convert"
Test.png
PIL調整尺寸與旋轉:
# -*- coding: utf-8 -*-
from PIL import Image
import os
#打開圖像得到一個PIL圖像對象
img = Image.open("./source/test.jpg")
#修改圖片大小,參數爲一元組
img = img.resize((100,200))
#使圖片逆時針選擇45度
img = img.rotate(45)
#存儲該張圖片
try:
img.save("test.png")
except IOError:
print "cannot convert"
Test.png
PIL複製粘貼圖像區域:
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from PIL import Image
import os
#打開圖像得到一個PIL圖像對象
img = Image.open("./source/test.jpg")
#從img中裁剪指定區域
region = img.crop((300,300,500,500))
#使裁剪部分逆時針選擇145度
region = region.rotate(145)
#將該區域粘貼至指定區域
img.paste(region,(100,100,300,300));
#存儲該張圖片
try:
img.save("test.png")
except IOError:
print "cannot convert"
Test.png
元組的使用中,座標原點爲左上角,區域劃分如下圖所示
使用Matplotlib進行基本圖像操作
Matplotlib簡介:
我們處理數學運算、繪製圖表,或者在圖像上繪製點、直線和曲線時, Matplotlib是個很好的類庫,具有比 PIL 更強大的繪圖功能。Matplotlib 可以繪製出較好的條形圖、餅狀圖、散點圖等,但是對於大多數計算機視覺應用來說,僅僅需要用到幾個繪圖命令。比如,我們想用點和線來表示一些事物,比如興趣點、對應點以及檢測出的物體。
使用Matplotlib繪製圖像、點、線
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
#打開圖像得到一個PIL圖像對象
img = Image.open("./source/test.jpg")
# 讀取圖像到數組中
im = array(img)
# 繪製圖像
imshow(im)
# 一些點
x = [100,100,400,400]
y = [200,500,200,500]
# 使用紅色星狀標記繪製點
plot(x,y,'r*')
# 繪製連接前兩個點的線
plot(x[:2],y[:2])
# 添加標題,顯示繪製的圖像
title('Plotting: "Test.jpg"')
show()
show() 命令首先打開圖形用戶界面(GUI),然後新建一個圖像窗口。該圖形用戶界面會循環阻斷腳本,然後暫停,直到最後一個圖像窗口關閉。在每個腳本里,你只能調用一次 show() 命令,而且通常是在腳本的結尾調用。
也可以使用axis(‘off’)命令使座標軸不顯示。
運行結果
在繪圖時,有很多選項可以控制圖像的顏色和樣式。
如:
plot(x,y) #默認爲藍色實線
plot(x,y,'r*') #紅色星狀標記
plot(x,y,'go-') #帶有圓圈標記的綠線
plot(x,y,'ks:') #帶有正方形標記的黑色虛線
標記 | 顏色 |
---|---|
‘b’ | 藍色 |
‘g’ | 綠色 |
‘r’ | 紅色 |
‘c’ | 青色 |
‘m’ | 品紅 |
‘y’ | 黃色 |
‘k’ | 黑色 |
‘w’ | 白色 |
標記 | 線型 |
---|---|
‘-‘ | 實線 |
‘–’ | 虛線 |
‘:’ | 點線 |
標記 | 形狀 |
---|---|
‘.’ | 點 |
‘o’ | 圓圈 |
’s’ | 正方形 |
‘*’ | 星形 |
‘+’ | 加號 |
‘x’ | 叉號 |
使用Matplotlib繪製圖像輪廓
繪製圖像的輪廓(或者其他二維函數的等輪廓線)在工作中非常有用。因爲繪製輪廓需要對每個座標 [x, y] 的像素值施加同一個閾值,所以首先需要將圖像灰度化,之後使用contour獲得輪廓圖像
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
# 讀取圖像到數組中,並灰度化
im = array(Image.open('./source/test.jpg').convert('L'))
#顯示時拋棄顏色信息
gray()
# 顯示輪廓圖像
contour(im, origin='image')
# 在原點的左上角顯示
axis('equal')
#關閉座標軸
axis('off')
show()
運行結果
使用Matplotlib繪製直方圖
圖像的直方圖用來表徵該圖像像素值的分佈情況。用一定數目的小區間(bin)來指定表徵像素值的範圍,每個小區間會得到落入該小區間表示範圍的像素數目。(灰度)圖像的直方圖可以使用 hist() 函數繪製:
hist() 函數的第二個參數指定小區間的數目。需要注意的是,因爲 hist() 只接受一維數組作爲輸入,所以我們在繪製圖像直方圖之前,必須先對圖像進行壓平處理。flatten() 方法將任意數組按照行優先準則轉換成一維數組。
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
# 讀取圖像到數組中,並灰度化
im = array(Image.open('./source/test.jpg').convert('L'))
# 直方圖圖像
hist(im.flatten(),128)
# 顯示
show()
運行結果
使用Matplotlib進行交互式標註
PyLab 庫中的 ginput() 函數可以實現交互式標註,用來標記一些點或者是一些訓練數據。
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
# 讀取圖像到數組中
im = array(Image.open('./source/test.jpg'))
# 顯示圖像
imshow(im)
print 'Please click 3 points'
#獲取點擊並將點擊座標保存在[x,y]列表中
x = ginput(3)
#輸出保存的數據
print 'you clicked:',x
show()
上面的腳本首先繪製一幅圖像,然後等待用戶在繪圖窗口的圖像區域點擊三次。程
序將這些點擊的座標 [x, y] 自動保存在 x 列表裏。
運行結果
you clicked: [(295.22704081632651, 210.72448979591837), (405.43112244897952, 66.846938775510239), (439.1045918367347, 180.11224489795921)]
結語:
本篇博客介紹了一些python基本的圖像操作,除了上述的PIL和Matplotlib,還經常會使用numpy直接操作圖像數組來達到操作圖像的目的,使用scipy完成更多更復雜的計算,我會把我的學習過程記錄下來,希望對大家有所幫助~