天天看點

Python-PIL 圖像處理基本操作(一)

Python-PIL 圖像處理基本操作(一)

一開始需要import

import os
import numpy as np
from PIL import Image, ImageDraw
           
##########################################
# 讀入圖檔,預設為RGB順序,讀出的變量img類型為Image類型, size為(width,height),但是為彩色三通道圖像
img = Image.open(os.path.join('images', '000906' + '.jpg'))

#顯示圖像
img.show()

#傳回圖像的格式,'JPEG'
print img.format 

#傳回圖像大小,(width,height)
print img.size 

#輸出RGB
print img.mode

#輸出元組('R', 'G', 'B')
print img.getbands() 

##########################################

#裝換Image格式為numpy數組array格式,進行圖像處理
#上面讀出的img還是Image格式,不能對其直接處理,需要對其轉換為array格式
#這裡需要注意的是未轉換格式之前img.size為(width,height),轉換之後img.shape為(height,width,3)

img = np.array(img, dtype = np.uint8)

#儲存圖檔
img.save(os.path.join('images', '13' + '.jpg'))

#如果需要儲存的圖檔變量是數組array形式的,需要先轉換為Image格式,然後再儲存
img = Image.fromarray(img.astype(np.uint8)) #由img.shape為(height,width,3)轉換為img.size為(width,height)

img.save(os.path.join('images', '13' + '.jpg'))

如果擷取圖像的最大值max()之類的,也把img轉換為array格式,再計算

##########################################

#縮放圖像
img = Image.open(os.path.join('images', '000906' + '.jpg'))

img_resized = img.resize((width,height)) #和讀入圖像的格式相同,也是先width後height

#如果想改變插值算法,可以如下(預設為NEAREST)

im_resized = im.resize((width,height), Image.BILINEAR)

#NEAREST:最近濾波。從輸入圖像中選取最近的像素作為輸出像素。它忽略了所有其他的像素。
#BILINEAR:雙線性濾波。在輸入圖像的2x2矩陣上進行線性插值。注意:PIL的目前版本,做下采樣時該濾波器使用了固定輸入模闆。
#BICUBIC:雙立方濾波。在輸入圖像的4x4矩陣上進行立方插值。注意:PIL的目前版本,做下采樣時該濾波器使用了固定輸入模闆。
#ANTIALIAS:平滑濾波。這是PIL 1.1.3版本中新的濾波器。對所有可以影響輸出像素的輸入像素進行高品質的重采樣濾波,以計算輸出像素值。在目前的PIL版本中,這個濾波器隻用于改變尺寸和縮略圖方法。
#注意:在目前的PIL版本中,ANTIALIAS濾波器是下采樣(例如,将一個大的圖像轉換為小圖)時唯一正确的濾波器。BILIEAR和BICUBIC濾波器使用固定的輸入模闆,用于固定比例的幾何變換和上采樣是最好的。

##########################################

#畫直線,矩形需要用到PIL的ImageDraw子產品

img = Image.open(os.path.join('images', '000906' + '.jpg')) #讀入圖像

draw = ImageDraw.Draw(img) #導入子產品

x1 =   # 第一個點列坐标
y1 =   #第一個點行坐标
x2 =  #第二個點列坐标
y2 =  #第二個點行坐标

#下面的這兩種形式[]或者()都可以,fill制定顔色RGB,width制定寬度
draw.line([x1,y1,x2,y2], fill = (, , ), width = )
draw.line((x1,y1,x2,y2), fill = (, , ), width = )

#下面是畫多條直線,可以畫出垂直的矩形或者旋轉的矩形,四個點坐标形式與上面相同
draw.line(((,),(,), (,), (,), (,)), fill = (, , ), width = )

img.show() #顯示
img.save(os.path.join('images', '13' + '.jpg')) #儲存在images/13.jpg

#畫矩形,這裡和上面畫直線差不多
img = Image.open(os.path.join('images', '000906' + '.jpg'))
draw = ImageDraw.Draw(img)

#x表示列坐标,y表示行坐标
x1 = 
y1 = 
x2 = 
y2 = 

#矩形左上角坐标和右下角坐标,後面是制定顔色RGB,紅色
draw.rectangle([x1, y1, x2, y2], outline=(, , ))

#在左上角添加紅色文字 ship
draw.text([x1, y1], 'ship', (, , ))

img.show() #顯示
img.save(os.path.join('images', '13' + '.jpg')) #儲存在images/13.jpg

##########################################

#圖像格式轉化

img = Image.open(os.path.join('images', '000906' + '.jpg'))

#轉化為灰階圖
gray=img.convert('L')

#使用函數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)

#将灰階圖轉換為array格式,此時大小為(height,width),如果是彩色圖像,為(height,width,3)
gray = np.array(gray, dtype = np.uint8)

##########################################

#拆分通道和合并通道

#拆分的通道,比如r,為灰階圖,Model:L, 大小為(width,height),還是為Image格式,不能直接處理,需要轉化為array格式
r,g,b = img.split()

#合并後的圖像 Model: RGB, 大小為(width,height),還是為Image格式,不能直接處理,需要轉化為array格式
img_merged = Image.merge('RGB',(r,g,b)) 
           

未完待續…

繼續閱讀