python skimage影象處理(一)
本文轉自 python數字影象處理
基於python指令碼語言開發的數字圖片處理包,比如PIL,Pillow, opencv, scikit-image等。
PIL和Pillow只提供最基礎的數字影象處理,功能有限;opencv實際上是一個c++庫,只是提供了python介面,更新速度非常慢。scikit-image是基於scipy的一款影象處理包,它將圖片作為numpy陣列進行處理,正好與matlab一樣,因此,我們最終選擇scikit-image進行數字影象處理。
Image讀出來的是PIL的型別,而skimage.io讀出來的資料是numpy格式的
-
import Image as img
-
import os
-
from matplotlib import pyplot as plot
-
from skimage import io,transform
-
#Image和skimage讀圖片
-
img_file1 = img.open('./CXR_png/MCUCXR_0042_0.png')
-
img_file2 = io.imread('./CXR_png/MCUCXR_0042_0.png')
-
輸出可以看出Img讀圖片的大小是圖片的(width, height);而skimage的是(height,width, channel)
-
#讀圖片後資料的大小:
-
print
"the picture's size: ", img_file1.size
-
print
"the picture's shape: ", img_file2.shape
-
the picture
's size: (4892, 4020)
-
the picture's shape: (4020, 4892)
-
#得到畫素:
-
print(img_file1.getpixel((500,1000)), img_file2[500][1000])
-
print(img_file1.getpixel((500,1000)), img_file2[1000][500])
-
print(img_file1.getpixel((1000,500)), img_file2[500][1000])
-
- (0, 139)
- (0, 0)
- (139, 139)
Img讀出來的圖片獲得某點畫素用getpixel((w,h))可以直接返回這個點三個通道的畫素值
skimage讀出來的圖片可以直接img_file2[0][0]獲得,但是一定記住它的格式,並不是你想的(channel,height,width)
圖片資訊
如果我們想知道一些skimage圖片資訊
-
from skimage import io, data
-
img = data.chelsea()
-
io.imshow(img)
-
print(type(img)) #顯示型別
-
print(img.shape) #顯示尺寸
-
print(img.shape[0]) #圖片高度
-
print(img.shape[1]) #圖片寬度
-
print(img.shape[2]) #圖片通道數
-
print(img.size) #顯示總畫素個數
-
print(img.max()) #最大畫素值
-
print(img.min()) #最小畫素值
-
print(img.mean()) #畫素平均值
-
print(img[0][0])#影象的畫素值
-
PIL image 檢視圖片資訊,可用如下的方法
-
print
type(img)
-
print img.size
#圖片的尺寸
-
print img.mode
#圖片的模式
-
print img.format
#圖片的格式
-
print(img.getpixel((0,0)))
#得到畫素:
-
#img讀出來的圖片獲得某點畫素用getpixel((w,h))可以直接返回這個點三個通道的畫素值
-
# 獲取影象的灰度值範圍
-
width = img.size[0]
-
height = img.size[1]
-
-
# 輸出圖片的畫素值
-
count = 0
-
for i in range(0, width):
-
for j in range(0, height):
-
if img.getpixel((i, j))>=0 and img.getpixel((i, j))<=255:
-
count +=1
-
print count
-
print(height*width)
-
skimage提供了io模組,顧名思義,這個模組是用來圖片輸入輸出操作的。為了方便練習,也提供一個data模組,裡面嵌套了一些示例圖片,我們可以直接使用。
skimage包的子模組
skimage包的全稱是scikit-image SciKit (toolkit for SciPy) ,它對scipy.ndimage進行了擴充套件,提供了更多的圖片處理功能。它是由python語言編寫的,由scipy 社群開發和維護。skimage包由許多的子模組組成,各個子模組提供不同的功能。主要子模組列表如下:
-
子模組名稱 主要實現功能
-
io 讀取、儲存和顯示圖片或視訊
-
data 提供一些測試圖片和樣本資料
-
color 顏色空間變換
-
filters 影象增強、邊緣檢測、排序濾波器、自動閾值等
-
draw 操作於numpy陣列上的基本圖形繪製,包括線條、矩形、圓和文字等
-
transform 幾何變換或其它變換,如旋轉、拉伸和拉東變換等
-
morphology 形態學操作,如開閉運算、骨架提取等
-
exposure 圖片強度調整,如亮度調整、直方圖均衡等
-
feature 特徵檢測與提取等
-
measure 影象屬性的測量,如相似性或等高線等
-
segmentation 影象分割
-
restoration 影象恢復
-
util 通用函式
從外部讀取圖片並顯示
讀取單張彩色rgb圖片,使用skimage.io.imread(fname)函式,帶一個引數,表示需要讀取的檔案路徑。顯示圖片使用skimage.io.imshow(arr)函式,帶一個引數,表示需要顯示的arr陣列(讀取的圖片以numpy陣列形式計算)。
-
from skimage import io
-
img=io.imread('d:/dog.jpg')
-
io.imshow(img)
-
讀取單張灰度圖片,使用skimage.io.imread(fname,as_grey=True)函式,第一個引數為圖片路徑,第二個引數為as_grey, bool型值,預設為False
-
from skimage import io
-
img=io.imread('d:/dog.jpg',as_grey=True)
-
io.imshow(img)
-
程式自帶圖片
skimage程式自帶了一些示例圖片,如果我們不想從外部讀取圖片,就可以直接使用這些示例圖片:
-
astronaut 航員圖片 coffee 一杯咖啡圖片
-
lena lena美女圖片 camera 拿相機的人圖片
-
coins 硬幣圖片 moon 月亮圖片
-
checkerboard 棋盤圖片 horse 馬圖片
-
page 書頁圖片 chelsea 小貓圖片
-
hubble_deep_field 星空圖片
text 文字圖片
-
clock 時鐘圖片 immunohistochemistry 結腸圖片
顯示這些圖片可用如下程式碼,不帶任何引數
-
from skimage import io, data
-
img=data.lena()
-
io.imshow(img)
-
圖片名對應的就是函式名,如camera圖片對應的函式名為camera(). 這些示例圖片存放在skimage的安裝目錄下面,路徑名稱為data_dir,我們可以將這個路徑打印出來看看
-
from skimage import data_dir
-
print(data_dir)
-
儲存圖片
使用io模組的imsave(fname,arr)函式來實現。第一個引數表示儲存的路徑和名稱,第二個引數表示需要儲存的陣列變數。
-
from skimage import io,data
-
img=data.chelsea()
-
io.imshow(img)
-
io.imsave('d:/cat.jpg',img)
-
儲存圖片的同時也起到了轉換格式的作用。如果讀取時圖片格式為jpg圖片,儲存為png格式,則將圖片從jpg圖片轉換為png圖片並儲存。
圖片資訊
如果我們想知道一些圖片資訊
-
from skimage import io, data
-
img = data.chelsea()
-
io.imshow(img)
-
print(type(img)) #顯示型別
-
print(img.shape) #顯示尺寸
-
print(img.shape[0]) #圖片高度
-
print(img.shape[1]) #圖片寬度
-
print(img.shape[2]) #圖片通道數
-
print(img.size) #顯示總畫素個數
-
print(img.max()) #最大畫素值
-
print(img.min()) #最小畫素值
-
print(img.mean()) #畫素平均值
-
print(img[0][0])#影象的畫素值
-
影象畫素的訪問與裁剪
圖片讀入程式中後,是以numpy陣列存在的。因此對numpy陣列的一切功能,對圖片也適用。對陣列元素的訪問,實際上就是對圖片畫素點的訪問。
彩色圖片訪問方式為:img[i,j,c]
i表示圖片的行數,j表示圖片的列數,c表示圖片的通道數(RGB三通道分別對應0,1,2)。座標是從左上角開始。
灰度圖片訪問方式為:gray[i,j]
例1:輸出小貓圖片的G通道中的第20行30列的畫素值
-
from skimage import io,data
-
img=data.chelsea()
-
pixel=img[20,30,1]
-
print(pixel)
-
例2:顯示紅色單通道圖片
-
from skimage import io,data
-
img=data.chelsea()
-
R=img[:,:,0]
-
io.imshow(R)
-
除了對畫素進行讀取,也可以修改畫素值。
例3:對小貓圖片隨機新增椒鹽噪聲
-
from skimage import io,data
-
import numpy as np
-
img=data.chelsea()
-
-
#隨機生成5000個椒鹽
-
rows,cols,dims=img.shape
-
for i in range(5000):
-
x=np.random.randint(0,rows)
-
y=np.random.randint(0,cols)
-
img[x,y,:]=255
-
io.imshow(img)
-
這裡用到了numpy包裡的random來生成隨機數,randint(0,cols)表示隨機生成一個整數,範圍在0到cols之間。
用img[x,y,:]=255這句來對畫素值進行修改,將原來的三通道畫素值,變為255
通過對陣列的裁剪,就可以實現對圖片的裁剪。
例4:對小貓圖片進行裁剪
-
from skimage import io,data
-
img=data.chelsea()
-
roi=img[80:180,100:200,:]
-
io.imshow(roi)
-
對多個畫素點進行操作,使用陣列切片方式訪問。切片方式返回的是以指定間隔下標訪問 該陣列的畫素值。下面是有關灰度影象的一些例子:
-
img[i,:] = im[j,:] # 將第 j 行的數值賦值給第 i 行
-
img[:,i] = 100 # 將第 i 列的所有數值設為 100
-
img[:100,:50].sum() # 計算前 100 行、前 50 列所有數值的和
-
img[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)
-
img[i].mean() # 第 i 行所有數值的平均值
-
img[:,-1] # 最後一列
-
img[-2,:] (or im[-2]) # 倒數第二行
-
最後我們再看兩個對畫素值進行訪問和改變的例子:
例5:將lena圖片進行二值化,畫素值大於128的變為1,否則變為0
-
from skimage import io,data,color
-
img=data.lena()
-
img_gray=color.rgb2gray(img)
-
rows,cols=img_gray.shape
-
for i in range(rows):
-
for j in range(cols):
-
if (img_gray[i,j]<=0.5):
-
img_gray[i,j]=0
-
else:
-
img_gray[i,j]=1
-
io.imshow(img_gray)
-
使用了color模組的rgb2gray()函式,將彩色三通道圖片轉換成灰度圖。轉換結果為float64型別的陣列,範圍為[0,1]之間。
將彩色三通道圖片轉換成灰度圖,最後變成unit8, float轉換為unit8是有資訊損失的。
-
img_path = 'data/dpclassifier/newtrain/test/1_0.png'
-
import Image as img
-
import os
-
from matplotlib import pyplot as plot
-
from skimage import io,transform, img_as_ubyte
-
img_file1 = img.open(img_path)
-
img_file1.show()
-
img_file2 = io.imread(img_path)
-
io.imshow(img_file2)
-
print(type(img_file1),img_file1.mode, type(img_file2),img_file2.shape, img_file2.dtype,img_file2.max(),img_file2.min(),img_file2.mean())
-
-
img_file22=skimage.color.rgb2gray(img_file2)
-
print(type(img_file22),img_file22.shape,img_file22.dtype,img_file22.max(),img_file22.min(),img_file22.mean() )
-
dst=img_as_ubyte(img_file22)
-
print(type(dst),dst.shape,dst.dtype, dst.max(), dst.min(), dst.mean())
-
結果
-
(<class
'PIL.PngImagePlugin.PngImageFile'>,
'RGB', <
type<