python PIL圖像處理

轉自簡書javascript

Image讀出來的是PIL的類型,而skimage.io讀出來的數據是numpy格式的php

#Image和skimage讀圖片 import Image as img import os from matplotlib import pyplot as plot from skimage import io,transform 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), [這也是爲何caffe在單獨測試時要要在代碼中設置:transformer.set_transpose('data',(2,0,1)),由於caffe能夠處理的圖片的數據格式是(channel,height,width),因此要轉換數據]css

#讀圖片後數據的大小: 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)html

在圖片上面加文字

#新建繪圖對象 draw = ImageDraw.Draw(image), #獲取圖像的寬和高 width, height = image.size; #** ImageFont模塊** #選擇文字字體和大小 setFont = ImageFont.truetype('C:/windows/fonts/Dengl.ttf', 20), #設置文字顏色 fillColor = "#ff0000" #寫入文字 draw.text((40, height - 100), u'廣告', font=setFont, fill=fillColor) 做者:刑素素 連接:http://www.jianshu.com/p/c77315a5435f 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。 

圖片信息

若是咱們想知道一些skimage圖片信息java

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 查看圖片信息,可用以下的方法python

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) 

使用python進行數字圖片處理,還得安裝Pillow包。雖然python裏面自帶一個PIL(python images library), 但這個庫如今已經中止更新了,因此使用Pillow, 它是由PIL發展而來的。windows

pil能處理的圖片類型
pil能夠處理光柵圖片(像素數據組成的的塊)。api

通道
一個圖片能夠包含一到多個數據通道,若是這些通道具備相同的維數和深度,Pil容許將這些通道進行疊加數組

模式
1 1位像素,黑和白,存成8位的像素 L 8位像素,黑白 P 8位像素,使用調色板映射到任何其餘模式 RGB 8位像素,真彩 RGBA 8位像素,真彩+透明通道 CMYK 8位像素,顏色隔離 YCbCr 8位像素,彩色視頻格式 I 32位整型像素 F 32位浮點型像素 

座標
Pil採起左上角爲(0,0)的座標系統瀏覽器

圖片的打開與顯示

from PIL import Image img=Image.open('d:/dog.png') img.show() 

雖然使用的是Pillow,但它是由PIL fork而來,所以仍是要從PIL中進行import. 使用open()函數來打開圖片,使用show()函數來顯示圖片。

這種圖片顯示方式是調用操做系統自帶的圖片瀏覽器來打開圖片,有些時候這種方式不太方便,所以咱們也可使用另上一種方式,讓程序來繪製圖片。

from PIL import Image import matplotlib.pyplot as plt img=Image.open('d:/dog.png') plt.figure("dog") plt.figure(num=1, figsize=(8,5),) plt.title('The image title') plt.axis('off') # 不顯示座標軸 plt.imshow(img) plt.show() 

這種方法雖然複雜了些,但推薦使用這種方法,它使用一個matplotlib的庫來繪製圖片進行顯示。matplotlib是一個專業繪圖的庫,至關於matlab中的plot,能夠設置多個figure,設置figure的標題,甚至可使用subplot在一個figure中顯示多張圖片。matplotlib 能夠直接安裝.
figure默認是帶axis的,若是沒有須要,咱們能夠關掉

plt.axis('off') 

圖像加標題

plt.title('The image title') 

matplotlib標準模式

plt.figure(num=5, figsize=(8,5),)
#plt.figure(num='newimage', figsize=(8,5),) plt.title('The image title', color='#0000FF') plt.imshow(lena) # 顯示圖片 plt.axis('off') # 不顯示座標軸 plt.show() 

CSDN-markdown編輯器語法——字體、字號與顏色


PIL image 查看圖片信息,可用以下的方法

print type(img) print img.size #圖片的尺寸 print img.mode #圖片的模式 print img.format #圖片的格式 

圖片的保存

img.save('d:/dog.jpg') 

就一行代碼,很是簡單。這行代碼不只能保存圖片,仍是轉換格式,如本例中,就由原來的png圖片保存爲了jpg圖片。


圖像通道\幾何變換\裁剪

PIL能夠對圖像的顏色進行轉換,並支持諸如24位彩色、8位灰度圖和二值圖等模式,簡單的轉換能夠經過Image.convert(mode)函數完 成,其中mode表示輸出的顏色模式,例如''L''表示灰度,''1''表示二值圖模式等。可是利用convert函數將灰度圖轉換爲二值圖時,是採用 固定的閾 值127來實現的,即灰度高於127的像素值爲1,而灰度低於127的像素值爲0。

彩色圖像轉灰度圖

from PIL import Image import matplotlib.pyplot as plt img=Image.open('d:/ex.jpg') gray=img.convert('L') plt.figure("beauty") plt.imshow(gray,cmap='gray') plt.axis('off') plt.title('The color image to gray image') plt.show() 

使用函數convert()來進行轉換,它是圖像實例對象的一個方法,接受一個 mode 參數,用以指定一種色彩模式,mode 的取值能夠是以下幾種:

· 1 (1-bit pixels, black and white, stored with one pixel per byte) · L (8-bit pixels, black and white) · P (8-bit pixels, mapped to any other mode using a colour palette) · RGB (3x8-bit pixels, true colour) · RGBA (4x8-bit pixels, true colour with transparency mask) · CMYK (4x8-bit pixels, colour separation) · YCbCr (3x8-bit pixels, colour video format) · I (32-bit signed integer pixels) · F (32-bit floating point pixels) 

通道分離與合併

from PIL import Image import matplotlib.pyplot as plt img=Image.open('d:/ex.jpg') #打開圖像 gray=img.convert('L') #轉換成灰度 r,g,b=img.split() #分離三通道 pic=Image.merge('RGB',(r,g,b)) #合併三通道 plt.figure("beauty") plt.subplot(2,3,1), plt.title('origin') plt.imshow(img),plt.axis('off') plt.subplot(2,3,2), plt.title('gray') plt.imshow(gray,cmap='gray'),plt.axis('off') plt.subplot(2,3,3), plt.title('merge') plt.imshow(pic),plt.axis('off') plt.subplot(2,3,4), plt.title('r') plt.imshow(r,cmap='gray'),plt.axis('off') plt.subplot(2,3,5), plt.title('g') plt.imshow(g,cmap='gray'),plt.axis('off') plt.subplot(2,3,6), plt.title('b') plt.imshow(b,cmap='gray'),plt.axis('off') plt.show() 

裁剪圖片

從原圖片中裁剪感興趣區域(roi),裁剪區域由4-tuple決定,該tuple中信息爲(left, upper, right, lower)。 Pillow左邊系統的原點(0,0)爲圖片的左上角。座標中的數字單位爲像素點。

from PIL import Image import matplotlib.pyplot as plt img=Image.open('d:/ex.jpg') #打開圖像 plt.figure("beauty") plt.subplot(1,2,1), plt.title('origin') plt.imshow(img),plt.axis('off') #box變量是一個四元組(左,上,右,下)。 box=(80,100,260,300) roi=img.crop(box) plt.subplot(1,2,2) plt.title('roi') plt.imshow(roi) plt.axis('off') plt.show() 

用plot繪製顯示出圖片後,將鼠標移動到圖片上,會在右下角出現當前點的座標,以及像素值。

**幾何變換 **
Image類有resize()、rotate()和transpose()方法進行幾何變換。
圖像的縮放和旋轉

dst = img.resize((128, 128))
dst = img.rotate(45) # 順時針角度表示 

轉換圖像

dst = im.transpose(Image.FLIP_LEFT_RIGHT) #左右互換 dst = im.transpose(Image.FLIP_TOP_BOTTOM) #上下互換 dst = im.transpose(Image.ROTATE_90) #順時針旋轉 dst = im.transpose(Image.ROTATE_180) dst = im.transpose(Image.ROTATE_270) 

transpose()和rotate()沒有性能差異。


python圖像處理庫Image模塊

建立一個新的圖片

Image.new(mode, size) Image.new(mode, size, color) 

層疊圖片
層疊兩個圖片,img2和img2,alpha是一個介於[0,1]的浮點數,若是爲0,效果爲img1,若是爲1.0,效果爲img2。固然img1和img2的尺寸和模式必須相同。這個函數能夠作出很漂亮的效果來,而圖形的算術加減後邊會說到。

Image.blend(img1, img2, alpha) 

composite可使用另一個圖片做爲蒙板(mask),全部的這三張圖片必須具有相同的尺寸,mask圖片的模式能夠爲「1」,「L」,「RGBA」

Image.composite(img1, img2, mask) 

添加水印

添加文字水印

from PIL import Image, ImageDraw,ImageFont im = Image.open("d:/pic/lena.jpg").convert('RGBA') txt=Image.new('RGBA', im.size, (0,0,0,0)) fnt=ImageFont.truetype("c:/Windows/fonts/Tahoma.ttf", 20) d=ImageDraw.Draw(txt) d.text((txt.size[0]-80,txt.size[1]-30), "cnBlogs",font=fnt, fill=(255,255,255,255)) out=Image.alpha_composite(im, txt) out.show() 

添加小圖片水印

from PIL import Image im = Image.open("d:/pic/lena.jpg") mark=Image.open("d:/logo_small.gif") layer=Image.new('RGBA', im.size, (0,0,0,0)) layer.paste(mark, (im.size[0]-150,im.size[1]-60)) out=Image.composite(layer,im,layer) out.show() 

PIL Image 圖像互轉 numpy 數組

將 PIL Image 圖片轉換爲 numpy 數組

im_array = np.array(im) # 也能夠用 np.asarray(im) 區別是 np.array() 是深拷貝,np.asarray() 是淺拷貝 

更多細節見python中的深拷貝與淺拷貝

numpy image 查看圖片信息,可用以下的方法

print img.shape print img.dtype 

將 numpy 數組轉換爲 PIL 圖片
這裏採用 matplotlib.image 讀入圖片數組,注意這裏讀入的數組是 float32 型的,範圍是 0-1,而 PIL.Image 數據是 uinit8 型的,範圍是0-255,因此要進行轉換:

import matplotlib.image as mpimg from PIL import Image lena = mpimg.imread('lena.png') # 這裏讀入的數據是 float32 型的,範圍是0-1 im = Image.fromarray(np.uinit8(lena*255)) im.show() 

PIL image 查看圖片信息,可用以下的方法

print type(img) print img.size #圖片的尺寸 print img.mode #圖片的模式 print img.format #圖片的格式 print(img.getpixel((0,0))[0])#獲得像素: #img讀出來的圖片得到某點像素用getpixel((w,h))能夠直接返回這個點三個通道的像素值 

圖像中的像素訪問

前面的一些例子中,咱們都是利用Image.open()來打開一幅圖像,而後直接對這個PIL對象進行操做。若是隻是簡單的操做還能夠,可是若是操做稍微複雜一些,就比較吃力了。所以,一般咱們加載完圖片後,都是把圖片轉換成矩陣來進行更加複雜的操做。
打開圖像並轉化爲矩陣,並顯示

from PIL import Image import numpy as np import matplotlib.pyplot as plt img=np.array(Image.open('d:/lena.jpg')) #打開圖像並轉化爲數字矩陣 plt.figure("dog") plt.imshow(img) plt.axis('off') plt.title('The image title') plt.show() 

調用numpy中的array()函數就能夠將PIL對象轉換爲數組對象。


查看圖片信息,可用以下的方法

PIL image 查看圖片信息,可用以下的方法

print type(img) print img.size #圖片的尺寸 print img.mode #圖片的模式 print img.format #圖片的格式 print(img.getpixel((0,0))[0])#獲得像素: #img讀出來的圖片得到某點像素用getpixel((w,h))能夠直接返回這個點三個通道的像素值 

numpy image 查看圖片信息,可用以下的方法

print img.shape print img.dtype 

若是是RGB圖片,那麼轉換爲array以後,就變成了一個rowscolschannels的三維矩陣,所以,咱們可使用

img[i,j,k] 

來訪問像素值。
例1:打開圖片,並隨機添加一些椒鹽噪聲

from PIL import Image import numpy as np import matplotlib.pyplot as plt img=np.array(Image.open('d:/ex.jpg')) #隨機生成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 plt.figure("beauty") plt.imshow(img) plt.axis('off') plt.show() 

例2:將lena圖像二值化,像素值大於128的變爲1,不然變爲0

from PIL import Image import numpy as np import matplotlib.pyplot as plt img=np.array(Image.open('d:/pic/lena.jpg').convert('L')) rows,cols=img.shape for i in range(rows): for j in range(cols): if (img[i,j]<=128): img[i,j]=0 else: img[i,j]=1 plt.figure("lena") plt.imshow(img,cmap='gray') plt.axis('off') plt.show() 

若是要對多個像素點進行操做,可使用數組切片方式訪問。切片方式返回的是以指定間隔下標訪問 該數組的像素值。下面是有關灰度圖像的一些例子:

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]) # 倒數第二行 

直接操做像素點

不但能夠對每一個像素點進行操做,並且,每個通道均可以獨立的進行操做。好比,將每一個像素點的亮度(不知道有沒有更專業的詞)增大20%

out = img.point(lambda i : i * 1.2) #注意這裏用到一個匿名函數(那個能夠把i的1.2倍返回的函數) 
argument * scale + offset  
e.g  
out = img.point(lambda i: i*1.2 + 10) 

圖像直方圖

咱們先來看兩個函數reshape和flatten:

假設咱們先生成一個一維數組:

vec=np.arange(15)
print vec 

若是咱們要把這個一維數組,變成一個3*5二維矩陣,咱們可使用reshape來實現

mat= vec.reshape(3,5)
print mat 

如今若是咱們返過來,知道一個二維矩陣,要變成一個一維數組,就不能用reshape了,只能用flatten. 咱們來看二者的區別

a1=mat.reshape(1,-1)  #-1表示爲任意,讓系統自動計算 print a1 a2=mat.flatten() print a2 

能夠看出,用reshape進行變換,實際上變換後仍是二維數組,兩個方括號,所以只能用flatten.

咱們要對圖像求直方圖,就須要先把圖像矩陣進行flatten操做,使之變爲一維數組,而後再進行統計

畫灰度圖直方圖
繪圖均可以調用matplotlib.pyplot庫來進行,其中的hist函數能夠直接繪製直方圖。
調用方式:

n, bins, patches = plt.hist(arr, bins=50, normed=1, facecolor='green', alpha=0.75) 

hist的參數很是多,但經常使用的就這五個,只有第一個是必須的,後面四個可選

arr: 須要計算直方圖的一維數組
bins: 直方圖的柱數,可選項,默認爲10
normed: 是否將獲得的直方圖向量歸一化。默認爲0
facecolor: 直方圖顏色
alpha: 透明度

返回值 :

n: 直方圖向量,是否歸一化由參數設定
bins: 返回各個bin的區間範圍
patches: 返回每一個bin裏面包含的數據,是一個list 
from PIL import Image import numpy as np import matplotlib.pyplot as plt img=np.array(Image.open('d:/pic/lena.jpg').convert('L')) plt.figure("lena") arr=img.flatten() n, bins, patches = plt.hist(arr, bins=256, normed=1, facecolor='green', alpha=0.75) plt.title('The image title') plt.show() 

彩色圖片直方圖
其實是和灰度直方圖同樣的,只是分別畫出三通道的直方圖,而後疊加在一塊兒。

from PIL import Image import numpy as np import matplotlib.pyplot as plt src=Image.open('d:/ex.jpg') r,g,b=src.split() plt.figure("lena") ar=np.array(r).flatten() plt.hist(ar, bins=256, normed=1,facecolor='r',edgecolor='r',hold=1) ag=np.array(g).flatten() plt.hist(ag, bins=256, normed=1, facecolor='g',edgecolor='g',hold=1) ab=np.array(b).flatten() plt.hist(ab, bins=256, normed=1, facecolor='b',edgecolor='b') plt.title('The image title') plt.show() 

因而可知,matplotlib的畫圖功能是很是強大的,直方圖只是其中很是小的一部分,更多的請參看官方文檔:
http://matplotlib.org/api/pyplot_summary.html


Python如何讀取指定文件夾下的全部圖像

''' Load the image files form the folder input: imgDir: the direction of the folder imgName:the name of the folder output: data:the data of the dataset label:the label of the datset ''' def load_Img(imgDir,imgFoldName): imgs = os.listdir(imgDir+imgFoldName) imgNum = len(imgs) data = np.empty((imgNum,1,12,12),dtype="float32") label = np.empty((imgNum,),dtype="uint8") for i in range (imgNum): img = Image.open(imgDir+imgFoldName+"/"+imgs[i]) arr = np.asarray(img,dtype="float32") data[i,:,:,:] = arr label[i] = int(imgs[i].split('.')[0]) return data,label 

調用方式

craterDir = "./data/CraterImg/Adjust/" foldName = "East_CraterAdjust12" data, label = load_Img(craterDir,foldName) 

Python圖形圖像處理庫ImageEnhance模塊圖像加強

可使用ImageEnhance模塊,其中包含了大量的預約義的圖片增強方式
增強器包括,色彩平衡,亮度平衡,對比度,銳化度等。經過使用這些增強器,能夠很輕鬆的作到圖片的色彩調整,亮度調整,銳化等操做,google picasa中提供的一些基本的圖片增強功能均可以實現。

顏色增強color用於調整圖片的色彩平衡,至關於彩色電視機的色彩調整。這個類實現了上邊提到的接口的enhance方法。

ImageEnhance.Color(img)#得到色彩增強器實例 

而後便可使用enhance(factor)方法進行調整。

亮度增強brightness用於調整圖片的明暗平衡。

ImageEnhance.Brightness(img)#得到亮度增強器實例 

factor=1返回一個黑色的圖片對象,0返回原始圖片對象

對比度增強contrast用於調整圖片的對比度,至關於彩色電視機的對比度調整。

ImageEnhance.Contrast(image) #得到對比度增強器實例 
import ImageEnhance enh = ImageEnhance.Contrast(im) enh.ehhance(1.5).show("50% more contrast") 

銳化度增強sharpness用於銳化/鈍化圖片。

ImageEnhance.Sharpness(image) #返回銳化增強器實例 

應該注意的是銳化操做的factor是一個0-2的浮點數,當factor=0時,返回一個徹底模糊的圖片對象,當factor=1時,返回一個徹底銳化的圖片對象,factor=1時,返回原始圖片對象


Python圖像處理庫ImageChops模塊

這個模塊主要包括對圖片的算術運算,叫作通道運算(channel operations)。這個模塊能夠用於多種途徑,包括一些特效製做,圖片整合,算數繪圖等等方面。
Invert:

ImageChops.invert(image) 

圖片反色,相似於集合操做中的求補集,最大值爲Max,每一個像素作減法,取出反色.
公式

out = MAX - image 

lighter:

ImageChops.lighter(image1, image2) 

darker:

ImageChops.darker(image1, image2) 

difference

ImageChops.difference(image1, image2) 

求出兩張圖片的絕對值,逐像素的作減法
multiply

ImageChops.multiply(image1, image2) 

將兩張圖片互相疊加,若是用純黑色與某圖片進行疊加操做,會獲得一個純黑色的圖片。若是用純白色與圖片做疊加,圖片不受影響。
計算的公式以下公式

out = img1 * img2 / MAX 

screen:

ImageChops.screen(image1, image2) 

先反色,後疊加。
公式

out = MAX - ((MAX - image1) * (MAX - image2) / MAX) 

add:

ImageChops.add(img1, img2, scale, offset) 

對兩張圖片進行算術加法,按照一下公式進行計算
公式

out = (img1+img2) / scale + offset 

若是尺度和偏移被忽略的化,scale=1.0, offset=0.0即
out = img1 + img2
subtract:

ImageChops.subtract(img1, img2, scale, offset) 

對兩張圖片進行算術減法:
公式

out = (img1-img2) / scale + offset 

Python圖形圖像處理庫ImageFilter模塊圖像濾鏡

ImageFilter是PIL的濾鏡模塊,經過這些預約義的濾鏡,能夠方便的對圖片進行一些過濾操做,從而去掉圖片中的噪音(部分的消除),這樣能夠下降未來處理的複雜度(如模式識別等)。

濾鏡名稱                      含義
ImageFilter.BLUR 模糊濾鏡 ImageFilter.CONTOUR 輪廓 ImageFilter.EDGE_ENHANCE 邊界增強 ImageFilter.EDGE_ENHANCE_MORE 邊界增強(閥值更大) ImageFilter.EMBOSS 浮雕濾鏡 ImageFilter.FIND_EDGES 邊界濾鏡 ImageFilter.SMOOTH 平滑濾鏡 ImageFilter.SMOOTH_MORE 平滑濾鏡(閥值更大) ImageFilter.SHARPEN 銳化濾鏡 

要使用PIL的濾鏡功能,須要引入ImageFilter模塊

import Image, ImageFilter def inHalf(img): w,h = img.size return img.resize((w/2, h/2)) def filterDemo(): img = Image.open("sandstone_half.jpg") #img = inHalf(img) imgfilted = img.filter(ImageFilter.SHARPEN) #imgfilted.show() imgfilted.save("sandstone_sharpen.jpg") if __name__ == "__main__": filterDemo() 
做者:jiandanjinxin 連接:https://www.jianshu.com/p/e8d058767dfa 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索