Image讀出來的是PIL的類型,而skimage.io讀出來的數據是numpy格式的
#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),所以要轉換數據]
#讀圖片后數據的大小:
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)
在圖片上面加文字
#新建繪圖對象
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.lxweimin.com/p/c77315a5435f
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
圖片信息
如果我們想知道一些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)
使用python進行數字圖片處理,還得安裝Pillow包。雖然python里面自帶一個PIL(python images library), 但這個庫現在已經停止更新了,所以使用Pillow, 它是由PIL發展而來的。
pil能處理的圖片類型
pil可以處理光柵圖片(像素數據組成的的塊)。
通道
一個圖片可以包含一到多個數據通道,如果這些通道具有相同的維數和深度,Pil允許將這些通道進行疊加
模式
1 1位像素,黑和白,存成8位的像素
L 8位像素,黑白
P 8位像素,使用調色板映射到任何其他模式
RGB 3×8位像素,真彩
RGBA 4×8位像素,真彩+透明通道
CMYK 4×8位像素,顏色隔離
YCbCr 3×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()
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()