Python圖像讀寫方法對比
1 實驗標(biāo)準(zhǔn)
因為訓(xùn)練使用的框架是Pytorch,因此讀取的實驗標(biāo)準(zhǔn)如下:
1、讀取分辨率都為1920x1080的5張圖片(png格式一張,jpg格式四張)并保存到數(shù)組。
2、將讀取的數(shù)組轉(zhuǎn)換為維度順序為CxHxW的Pytorch張量,并保存到顯存中(我使用GPU訓(xùn)練),其中三個通道的順序為RGB。
3、記錄各個方法在以上操作中所耗費的時間。因為png格式的圖片大小差不多是質(zhì)量有微小差異的jpg格式的10倍,所以數(shù)據(jù)集通常不會用png來保存,就不比較這兩種格式的讀取時間差異了。
寫入的實驗標(biāo)準(zhǔn)如下:
1、將5張1920x1080的5張圖像對應(yīng)的Pytorch張量轉(zhuǎn)換為對應(yīng)方法可使用的數(shù)據(jù)類型數(shù)組。
2、以jpg格式保存五張圖片。
3、記錄各個方法保存圖片所耗費的時間。
2 實驗情況
2.1 cv2
因為有GPU,所以cv2讀取圖片有兩種方式:
1、先把圖片都讀取為一個numpy數(shù)組,再轉(zhuǎn)換成保存在GPU中的pytorch張量。
2、初始化一個保存在GPU中的pytorch張量,然后將每張圖直接復(fù)制進(jìn)這個張量中。
第一種方式實驗代碼如下:
import os, torch import cv2 as cv import numpy as np from time import time read_path = 'D:test' write_path = 'D:test\\write\\' # cv2讀取 1 start_t = time() imgs = np.zeros([5, 1080, 1920, 3]) for img, i in zip(os.listdir(read_path), range(5)): img = cv.imread(filename=os.path.join(read_path, img)) imgs[i] = img imgs = torch.tensor(imgs).to('cuda')[...,[2,1,0]].permute([0,3,1,2])/255 print('cv2 讀取時間1:', time() - start_t) # cv2保存 start_t = time() imgs = (imgs.permute([0,2,3,1])[...,[2,1,0]]*255).cpu().numpy() for i in range(imgs.shape[0]): cv.imwrite(write_path + str(i) + '.jpg', imgs[i]) print('cv2 保存時間:', time() - start_t)
實驗結(jié)果:
cv2 讀取時間1: 0.39693760871887207
cv2 保存時間: 0.3560612201690674
第二種方式實驗代碼如下:
import os, torch import cv2 as cv import numpy as np from time import time read_path = 'D:test' write_path = 'D:test\\write\\' # cv2讀取 2 start_t = time() imgs = torch.zeros([5, 1080, 1920, 3], device='cuda') for img, i in zip(os.listdir(read_path), range(5)): img = torch.tensor(cv.imread(filename=os.path.join(read_path, img)), device='cuda') imgs[i] = img imgs = imgs[...,[2,1,0]].permute([0,3,1,2])/255 print('cv2 讀取時間2:', time() - start_t) # cv2保存 start_t = time() imgs = (imgs.permute([0,2,3,1])[...,[2,1,0]]*255).cpu().numpy() for i in range(imgs.shape[0]): cv.imwrite(write_path + str(i) + '.jpg', imgs[i]) print('cv2 保存時間:', time() - start_t)
實驗結(jié)果:
cv2 讀取時間2: 0.23636841773986816
cv2 保存時間: 0.3066873550415039
2.2 matplotlib
同樣兩種讀取方式,第一種代碼如下:
import os, torch import numpy as np import matplotlib.pyplot as plt from time import time read_path = 'D:test' write_path = 'D:test\\write\\' # matplotlib 讀取 1 start_t = time() imgs = np.zeros([5, 1080, 1920, 3]) for img, i in zip(os.listdir(read_path), range(5)): img = plt.imread(os.path.join(read_path, img)) imgs[i] = img imgs = torch.tensor(imgs).to('cuda').permute([0,3,1,2])/255 print('matplotlib 讀取時間1:', time() - start_t) # matplotlib 保存 start_t = time() imgs = (imgs.permute([0,2,3,1])).cpu().numpy() for i in range(imgs.shape[0]): plt.imsave(write_path + str(i) + '.jpg', imgs[i]) print('matplotlib 保存時間:', time() - start_t)
實驗結(jié)果:
matplotlib 讀取時間1: 0.45380306243896484
matplotlib 保存時間: 0.768944263458252
第二種方式實驗代碼:
import os, torch import numpy as np import matplotlib.pyplot as plt from time import time read_path = 'D:test' write_path = 'D:test\\write\\' # matplotlib 讀取 2 start_t = time() imgs = torch.zeros([5, 1080, 1920, 3], device='cuda') for img, i in zip(os.listdir(read_path), range(5)): img = torch.tensor(plt.imread(os.path.join(read_path, img)), device='cuda') imgs[i] = img imgs = imgs.permute([0,3,1,2])/255 print('matplotlib 讀取時間2:', time() - start_t) # matplotlib 保存 start_t = time() imgs = (imgs.permute([0,2,3,1])).cpu().numpy() for i in range(imgs.shape[0]): plt.imsave(write_path + str(i) + '.jpg', imgs[i]) print('matplotlib 保存時間:', time() - start_t)
實驗結(jié)果:
matplotlib 讀取時間2: 0.2044532299041748
matplotlib 保存時間: 0.4737534523010254
需要注意的是,matplotlib讀取png格式圖片獲取的數(shù)組的數(shù)值是在[0,1][0,1]范圍內(nèi)的浮點數(shù),而jpg格式圖片卻是在[0,255][0,255]范圍內(nèi)的整數(shù)。所以如果數(shù)據(jù)集內(nèi)圖片格式不一致,要注意先轉(zhuǎn)換為一致再讀取,否則數(shù)據(jù)集的預(yù)處理就麻煩了。
2.3 PIL
PIL的讀取與寫入并不能直接使用pytorch張量或numpy數(shù)組,要先轉(zhuǎn)換為Image類型,所以很麻煩,時間復(fù)雜度上肯定也是占下風(fēng)的,就不實驗了。
2.4 torchvision
torchvision提供了直接從pytorch張量保存圖片的功能,和上面讀取最快的matplotlib的方法結(jié)合,代碼如下:
import os, torch import matplotlib.pyplot as plt from time import time from torchvision import utils read_path = 'D:test' write_path = 'D:test\\write\\' # matplotlib 讀取 2 start_t = time() imgs = torch.zeros([5, 1080, 1920, 3], device='cuda') for img, i in zip(os.listdir(read_path), range(5)): img = torch.tensor(plt.imread(os.path.join(read_path, img)), device='cuda') imgs[i] = img imgs = imgs.permute([0,3,1,2])/255 print('matplotlib 讀取時間2:', time() - start_t) # torchvision 保存 start_t = time() for i in range(imgs.shape[0]): utils.save_image(imgs[i], write_path + str(i) + '.jpg') print('torchvision 保存時間:', time() - start_t)
實驗結(jié)果:
matplotlib 讀取時間2: 0.15358829498291016
torchvision 保存時間: 0.14760661125183105
可以看出這兩個是最快的讀寫方法。另外,要讓圖片的讀寫盡量不影響訓(xùn)練進(jìn)程,我們還可以讓這兩個過程與訓(xùn)練并行。另外,utils.save_image可以將多張圖片拼接成一張來保存,具體使用方法如下:
utils.save_image(tensor = imgs, # 要保存的多張圖片張量 shape = [n, C, H, W] fp = 'test.jpg', # 保存路徑 nrow = 5, # 多圖拼接時,每行所占的圖片數(shù) padding = 1, # 多圖拼接時,每張圖之間的間距 normalize = True, # 是否進(jìn)行規(guī)范化,通常輸出圖像用tanh,所以要用規(guī)范化 range = (-1,1)) # 規(guī)范化的范圍
以上就是Python圖像讀寫方法對比的詳細(xì)內(nèi)容,更多關(guān)于python 圖像讀寫的資料請關(guān)注腳本之家其它相關(guān)文章!
- Python空間數(shù)據(jù)處理之GDAL讀寫遙感圖像
- Python各類圖像庫的圖片讀寫方式總結(jié)(推薦)
- python 對一幅灰度圖像進(jìn)行直方圖均衡化
- 詳解基于python的圖像Gabor變換及特征提取
- Python+OpenCV圖像處理——圖像二值化的實現(xiàn)
- Python+OpenCV圖像處理——實現(xiàn)輪廓發(fā)現(xiàn)
- Python+OpenCV圖像處理——實現(xiàn)直線檢測
- Python+OpenCV圖像處理—— 色彩空間轉(zhuǎn)換
- 如何使用Python調(diào)整圖像大小
- Python Opencv圖像處理基本操作代碼詳解
- Python圖像處理二值化方法實例匯總
相關(guān)文章
python實現(xiàn)簡易的學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實現(xiàn)簡易的學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05基于Google的Python編碼規(guī)范標(biāo)準(zhǔn)
這篇文章主要介紹了基于Google的Python編碼規(guī)范標(biāo)準(zhǔn),其中包含了分號,行長度,括號,縮進(jìn),空行,空格等基本符號的使用規(guī)則,有需要的朋友可以參考下2021-08-08Python進(jìn)階教程之創(chuàng)建本地PyPI倉庫
pypi是一個python包的倉庫,里面有很多別人寫好的python庫,你可以通過easy_install或者pip進(jìn)行安裝,下面這篇文章主要給大家介紹了關(guān)于Python進(jìn)階教程之創(chuàng)建本地PyPI倉庫的相關(guān)資料,需要的朋友可以參考下2021-10-10Python利用hashlib實現(xiàn)文件MD5碼的批量存儲
這篇文章主要為大家詳細(xì)介紹了如何用Python和hashlib實現(xiàn)文件MD5碼的批量存儲功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2023-05-05