溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

發(fā)布時(shí)間:2020-09-17 02:07:16 來(lái)源:腳本之家 閱讀:131 作者:Madcola 欄目:開(kāi)發(fā)技術(shù)

最近在研究深度學(xué)習(xí)視覺(jué)相關(guān)的東西,經(jīng)常需要寫python代碼搭建深度學(xué)習(xí)模型。比如寫CNN模型相關(guān)代碼時(shí),我們需要借助python圖像庫(kù)來(lái)讀取圖像并進(jìn)行一系列的圖像處理工作。我最常用的圖像庫(kù)當(dāng)然是opencv,很強(qiáng)大很好用,但是opencv也有一些坑,不注意的話也會(huì)搞出大麻煩。近期我也在看一些別人寫的代碼,因?yàn)閭€(gè)人習(xí)慣不一樣,他們?cè)谧錾疃葘W(xué)習(xí)時(shí)用于圖片讀取的圖像庫(kù)各不相同,從opencv到PIL再到skimage等等各種庫(kù)都有,有些庫(kù)讀進(jìn)來(lái)的圖片存儲(chǔ)方式也不太一樣,如果不好好總結(jié)這些主流圖像讀寫庫(kù)特點(diǎn)的話,以后看代碼寫代碼都會(huì)遇坑無(wú)數(shù)。這篇文章就總結(jié)了以下主流Python圖像庫(kù)的一些基本使用方法和需要注意的地方:

1.opencv
2.PIL(pillow)
3.matplotlib.image
4.scipy.misc
5.skimage

opencv: cv2.imread

opencv作為我最常用的圖像處理庫(kù),當(dāng)然第一個(gè)介紹,并且介紹得比較全面。毋庸置疑,opencv是今天介紹得所有圖像庫(kù)中最全面也最強(qiáng)大的庫(kù),如果我們只想掌握一個(gè)圖像庫(kù),我覺(jué)得opencv庫(kù)肯定是最適合不過(guò)了。

圖片讀取操作

import cv2
import numpy as np

#讀入圖片:默認(rèn)彩色圖,cv2.IMREAD_GRAYSCALE灰度圖,cv2.IMREAD_UNCHANGED包含alpha通道
img = cv2.imread('1.jpg')
cv2.imshow('src',img)
print(img.shape) # (h,w,c)
print(img.size) # 像素總數(shù)目
print(img.dtype)
print(img)
cv2.waitKey()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

值得注意的是,opencv讀進(jìn)來(lái)的圖片已經(jīng)是一個(gè)numpy矩陣了,彩色圖片維度是(高度,寬度,通道數(shù))。數(shù)據(jù)類型是uint8。

#gray = cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE) #灰度圖
#cv2.imshow('gray',gray)
#也可以這么寫,先讀入彩色圖,再轉(zhuǎn)灰度圖
src = cv2.imread('1.jpg')
gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',gray)
print(gray.shape)
print(gray.size)
print(gray)
cv2.waitKey()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

上面提到了兩種獲取灰度圖的方式,讀進(jìn)來(lái)的灰度圖的矩陣格式是(高度,寬度)。

#注意,計(jì)算圖片路徑是錯(cuò)的,Opencv也不會(huì)提醒你,但print img時(shí)得到的結(jié)果是None
img2 = cv2.imread('2.jpg')
print(img2)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#如何解決“讀到的圖片不存在的問(wèn)題”? #加入判斷語(yǔ)句,如果為空,做異常處理
img2 = cv2.imread('2.jpg')
if img2 == None:
  print('fail to load image!')

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

圖片矩陣變換

opencv讀入圖片的矩陣格式是:(height,width,channels)。而在深度學(xué)習(xí)中,因?yàn)橐獙?duì)不同通道應(yīng)用卷積,所以會(huì)采取另一種方式:(channels,height,width)。為了應(yīng)對(duì)該要求,我們可以這么做

#注意到,opencv讀入的圖片的彩色圖是一個(gè)channel last的三維矩陣(h,w,c),即(高度,寬度,通道)
#有時(shí)候在深度學(xué)習(xí)中用到的的圖片矩陣形式可能是channel first,那我們可以這樣轉(zhuǎn)一下
print(img.shape)
img = img.transpose(2,0,1)
print(img.shape)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

在深度學(xué)習(xí)搭建CNN時(shí),往往要做相應(yīng)的圖像數(shù)據(jù)處理,比如圖像要擴(kuò)展維度,比如擴(kuò)展成(batch_size,channels,height,width)。

對(duì)于這種要求,我們可以這么做。

#有時(shí)候還要擴(kuò)展維度,比如有時(shí)候我們需要預(yù)測(cè)單張圖片,要在要加一列做圖片的個(gè)數(shù),可以這么做
img = np.expand_dims(img, axis=0)
print(img.shape)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

上面提到的是預(yù)測(cè)階段時(shí)預(yù)測(cè)單張圖片的擴(kuò)展維度的操作,如果是訓(xùn)練階段,構(gòu)建batch,即得到這種形式:(batch_size,channels,height,width)。我一般喜歡這么做

data_list = [] 
loop:
  im = cv2.imread('xxx.png')
  data_list.append(im)
data_arr = np.array(data_list)

這樣子就能構(gòu)造成我們想要的形式了。

圖片歸一化

#因?yàn)閛pencv讀入的圖片矩陣數(shù)值是0到255,有時(shí)我們需要對(duì)其進(jìn)行歸一化為0~1
img3 = cv2.imread('1.jpg')
img3 = img3.astype("float") / 255.0 #注意需要先轉(zhuǎn)化數(shù)據(jù)類型為float
print(img3.dtype)
print(img3)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

存儲(chǔ)圖片

#存儲(chǔ)圖片
cv2.imwrite('test1.jpg',img3) #得到的是全黑的圖片,因?yàn)槲覀儼阉鼩w一化了
#所以要得到可視化的圖,需要先*255還原
img3 = img3 * 255
cv2.imwrite('test2.jpg',img3) #這樣就可以看到彩色原圖了

opencv大坑之BGR

opencv對(duì)于讀進(jìn)來(lái)的圖片的通道排列是BGR,而不是主流的RGB!謹(jǐn)記!

#opencv讀入的矩陣是BGR,如果想轉(zhuǎn)為RGB,可以這么轉(zhuǎn)
img4 = cv2.imread('1.jpg')
img4 = cv2.cvtColor(img4,cv2.COLOR_BGR2RGB)

訪問(wèn)像素

#訪問(wèn)像素
print(img4[10,10]) #3channels
print(gray[10,10]) #1channel
img4[10,10] = [255,255,255]
gray[10,10] = 255
print(img4[10,10]) #3channels
print(gray[10,10]) #1channel

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

ROI操作

#roi操作
roi = img4[200:550,100:450,:]
cv2.imshow('roi',roi)
cv2.waitKey()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

通道操作

#分離通道
img5 = cv2.imread('1.jpg')
b,g,r = cv2.split(img5)
#合并通道
img5 = cv2.merge((b,g,r))
#也可以不拆分
img5[:,:,2] = 0 #將紅色通道值全部設(shè)0

PIL:PIL.Image.open

圖片讀取

from PIL import Image
import numpy as np

PIL即Python Imaging Library,也即為我們所稱的Pillow,是一個(gè)很流行的圖像庫(kù),它比opencv更為輕巧,正因如此,它深受大眾的喜愛(ài)。

圖像讀寫

PIL讀進(jìn)來(lái)的圖像是一個(gè)對(duì)象,而不是我們所熟知的numpy 矩陣。

img = Image.open('1.jpg')
print(img.format) 
print(img.size) #注意,省略了通道 (w,h)
print(img.mode) #L為灰度圖,RGB為真彩色,RGBA為加了透明通道
img.show() # 顯示圖片

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

灰度圖的獲取

gray = Image.open('1.jpg').convert('L')
gray.show()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#讀取不到圖片會(huì)拋出異常IOError,我們可以捕捉它,做異常處理
try:
  img2 = Image.open('2.jpg')
except IOError:
  print('fail to load image!')

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#pillow讀進(jìn)來(lái)的圖片不是矩陣,我們將圖片轉(zhuǎn)矩陣,channel last
arr = np.array(img3)
print(arr.shape)
print(arr.dtype)
print(arr)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

灰度圖的轉(zhuǎn)化與彩圖轉(zhuǎn)化一樣

arr_gray = np.array(gray)
print(arr_gray.shape)
print(arr_gray.dtype)
print(arr_gray)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

存儲(chǔ)圖片

#矩陣再轉(zhuǎn)為圖像
new_im = Image.fromarray(arr)
new_im.save('3.png')

圖像操作

#分離合并通道
r, g, b = img.split()
img = Image.merge("RGB", (b, g, r))
img = img.copy() #復(fù)制圖像

ROI獲取

img3 = Image.open('1.jpg')
roi = img3.crop((0,0,300,300)) #(左上x(chóng),左上y,右下x,右下y)坐標(biāo)
roi.show()

matplotlib:matplotlib.image.imread

matplotlib是一個(gè)科學(xué)繪圖神器,用的人非常多。

import matplotlib.pyplot as plt
import numpy as np
image = plt.imread('1.jpg')
plt.imshow(image)
plt.show()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#也可以關(guān)閉顯示x,y軸上的數(shù)字
image = plt.imread('1.jpg')
plt.imshow(image)
plt.axis('off')
plt.show()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#plt.imread讀入的就是一個(gè)矩陣,跟opencv一樣,但彩圖讀進(jìn)的是RGB,與opencv有區(qū)別
print(image.shape) # (h,w,c)
print(image.size)
print(image.dtype) 
print(image)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

im_r = image[:,:,0] #紅色通道
plt.imshow(im_r)
plt.show()
#此時(shí)會(huì)發(fā)現(xiàn)顯示的是熱量圖,不是我們預(yù)想的灰度圖,可以添加 cmap 參數(shù)解決
plt.imshow(im_r,cmap='Greys_r')
plt.show()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#與opencv結(jié)合使用
import cv2
im2 = cv2.imread('1.jpg')
plt.imshow(im2)
plt.axis('off')
plt.show()
#發(fā)現(xiàn)圖像顏色怪怪的,原因當(dāng)然是我們前面提到的RGB順序不同的原因啦,轉(zhuǎn)一下就好
im2 = cv2.cvtColor(im2,cv2.COLOR_BGR2RGB)
plt.imshow(im2)
plt.axis('off')
plt.show()
#所以無(wú)論用什么庫(kù)讀進(jìn)圖片,只要把圖片改為矩陣,那么matplotlib就可以處理了

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#再試一試pillow和matplotlib結(jié)合
from PIL import Image
im3 = Image.open('1.jpg')
im3 = np.array(im3)
plt.figure(1)
plt.imshow(im3)
plt.axis('off')
#存儲(chǔ)圖像,注意,必須在show之前savefig,否則存儲(chǔ)的圖片一片空白
plt.savefig('timo.jpg')
plt.show()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

#最后以一個(gè)綜合例子總結(jié)matplotlib最基本的圖片顯示技巧吧
im_lol1 = plt.imread('lol.jpg')
im_lol2 = plt.imread('1.jpg')
figure = plt.figure(figsize=(20,10)) # 調(diào)整顯示圖片的大小
'''
figsize參數(shù):指定繪圖對(duì)象的寬度和高度,單位為英寸;dpi參數(shù)指定繪圖對(duì)象的分辨率,
即每英寸多少個(gè)像素,缺省值為80。因此本例中所創(chuàng)建的圖表窗口的寬度為8*80 = 640像素
'''
plt.axis("off")#不顯示刻度 
ax = figure.add_subplot(121) # 圖片以1行2列的形式顯示
plt.axis('off')
ax.imshow(im_lol1) #第一張圖
ax.set_title('lol image 1')#給圖片加titile 
ax = figure.add_subplot(122) 
plt.axis('off')
ax.imshow(im_lol2) 
ax.set_title('lol image 2')#給圖片加titile 

plt.savefig('twp.jpg')
plt.show()

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

scipy.misc:scipy.misc.imread

from scipy import misc
import matplotlib.pyplot as plt
im = misc.imread('1.jpg')
print(im.dtype)
print(im.size)
print(im.shape)
misc.imsave('misc1.png',im)
plt.imshow(im)
plt.show()
print(im)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

可以看到,有warining,提示我們imread和imsave在后來(lái)的版本將會(huì)被棄用,叫我們使用imageio.imread和imageio.imwrite。

我們根據(jù)她的提示,使用imageio模塊進(jìn)行圖片讀寫,warning也就沒(méi)有了。

import imageio
im2 = imageio.imread('1.jpg')
print(im2.dtype)
print(im2.size)
print(im2.shape)
plt.imshow(im)
plt.show()
print(im2)
imageio.imsave('imageio.png',im2)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

skimage:skimage.io.imread

from skimage import io

im = io.imread('1.jpg')
print(im.shape) # numpy矩陣,(h,w,c)
print(im.dtype)
print(im.size)
io.imshow(im)
io.imsave('sk.png',im)
print(im)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

圖像也是以numpy array形式讀入。

灰度圖的獲取方式:

im2 = io.imread('1.jpg',as_grey=True) #讀入灰度圖
print(im2.dtype)
print(im2.size)
print(im2.shape)
io.imshow(im2)
io.imsave('sk_gray.png',im2)
io.show()
print(im2)

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

可以看到,灰度圖像的矩陣的值被歸一化了,注意注意!

也可以以這種方式獲得灰度圖:

from skimage import color
im3 = io.imread('1.jpg')
im3 = color.rgb2grey(im3)
print(im3.dtype)
print(im3.size)
print(im3.shape)
io.imshow(im3)
io.show()

'''
skimage.color.rgb2grey(rgb)
skimage.color.rgb2hsv(rgb)
skimage.color.rgb2lab(rgb)
skimage.color.gray2rgb(image)
skimage.color.hsv2rgb(hsv)
skimage.color.lab2rgb(lab)

'''

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

總結(jié)

  1. 除了opencv讀入的彩色圖片以BGR順序存儲(chǔ)外,其他所有圖像庫(kù)讀入彩色圖片都以RGB存儲(chǔ)。
  2. 除了PIL讀入的圖片是img類之外,其他庫(kù)讀進(jìn)來(lái)的圖片都是以numpy 矩陣。
  3. 各大圖像庫(kù)的性能,老大哥當(dāng)屬opencv,無(wú)論是速度還是圖片操作的全面性,都屬于碾壓的存在,畢竟他是一個(gè)巨大的cv專用庫(kù)。下面那張圖就是我從知乎盜來(lái)的一張關(guān)于各個(gè)主流圖像庫(kù)的一些性能比較圖,從測(cè)試結(jié)果看來(lái),opencv確實(shí)勝出太多了。

Python各類圖像庫(kù)的圖片讀寫方式總結(jié)(推薦)

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI