OpenCV-Python教程:讀取圖像、顯示、寫入圖像(imread,imshow,imwrite,waitKey)


原文鏈接:http://www.juzicode.com/archives/5395

返回Opencv-Python教程

這篇文件介紹怎么用OpenCV-Python從靜態圖片文件中獲取圖像、顯示圖像,以及怎么保存靜態圖像文件。在OpenCV-Python教程:從視頻文件或相機獲取圖像、寫視頻文件 一文中介紹怎么讀取和保存視頻文件。

 

1、讀取圖片imread()

imread()方法在第1個位置參數傳入圖像文件的路徑,如果讀取文件成功返回一個numpy數組,如果獲取失敗將返回None。

這里需要注意的是獲取圖像失敗並不會拋異常,而是得到一個None,后面的imshow(),imwrite()等方法如果直接使用反而會導致異常。

下面的3個imread()的例子分別是錯誤的路徑、非圖片文件、正確路徑的圖片文件:

import cv2

print('cv2.__version__:',cv2.__version__)
img = cv2.imread('..\\lena2.jpg')  #錯誤路徑
print('img:',img)
print('type(img):',type(img))

img = cv2.imread('..\\1.txt')  #非圖片文件
print('img:',img)
print('type(img):',type(img))

img = cv2.imread('..\\lena.jpg') #圖片文件,正確路徑
print('img:',img)
print('type(img):',type(img))

運行結果:

cv2.__version__: 4.5.2
img: None
type(img): <class 'NoneType'>  #錯誤路徑
img: None
type(img): <class 'NoneType'>  #非圖片文件
img: [[[128 138 225]
  [127 137 224]
  [126 136 224]
  ...
  ...
  [ 81  68 176]
  [ 81  72 183]
  [ 84  74 188]]]
type(img): <class 'numpy.ndarray'> #圖片文件,正確路徑

 

另外讀取圖像還可以在第2個位置參數寫入如下3種模式:

cv2.IMREAD_COLOR 缺省方式,讀取圖像為BGR 8-bit 格式.
cv2.IMREAD_UNCHANGED 圖像格式不做任何改變,可用在讀取帶alpha通道的圖片
cv2.IMREAD_GRAYSCALE 讀取圖像為轉換為灰度圖

下面這個例子從3張圖片中按照IMREAD_UNCHANGED模式讀取,通過返回numpy數組的shape屬性可以看到不同的3張圖片的通道數的差異:

import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)

img = cv2.imread('..\\lena.jpg',cv2.IMREAD_UNCHANGED)
print('img.shape:',img.shape)
img2 = cv2.imread('..\\opencv-logo.png',cv2.IMREAD_UNCHANGED )
print('img2.shape:',img2.shape)
img3 = cv2.imread('..\\left05.jpg',cv2.IMREAD_UNCHANGED )
print('img3.shape:',img3.shape)

運行結果:

VX公眾號: 桔子code / juzicode.com
cv2.__version__: 3.4.1
img.shape: (512, 512, 3)  #3通道圖像
img2.shape: (739, 600, 4) #4通道圖像
img3.shape: (480, 640)    #灰度圖

 

需要注意的是圖像的寬度是width=cols=img.shape[1],高度height=rows=img.shape[0]。

 

2、顯示圖像imshow()

imshow()可以用來顯示圖片,第1個參數為顯示窗口名稱,第2個參數是imread()等方法生成的圖像實例。

為了觀察顯示效果,一般需要配合waitKey()使用,waitKey()傳入的參數如果為0,會無限等待直到任何按鍵按下,或者傳入其他數值參數表示等待時長,單位為ms,時長結束后顯示圖像窗口會關閉。

下面這個例子中增加了讀出圖像的判斷,如果獲取圖像為None則退出,如果獲取圖像成功才顯示。

這個例子中waitKey()入參使用了0和5000,第1次的0表示無限等待,直到按鍵按下,第2次表示等待5000ms后顯示窗口自動關閉。

import sys
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)

img = cv2.imread('..\\lena.jpg')
#print('img:',img)
print('type(img):',type(img))

if img is None:
    print('讀出的圖像為空')
    sys.exit(-1)

cv2.imshow('lena',img)
cv2.waitKey(0)

cv2.imshow('lena2',img)
cv2.waitKey(5000)

運行結果:

VX公眾號: 桔子code / juzicode.com
cv2.__version__: 4.5.2
type(img): <class 'numpy.ndarray'>

 

除了前面用imshow()顯示圖像,還可以通過resizeWindow()等函數調整窗口大小再顯示圖像,如果顯示的圖像太多,還可以使用destroyWindow()銷毀顯示窗口。

 

2.1、調整窗口nameWindow()、resizeWindow()

使用imshow()方法顯示圖像時,默認是以圖像的像素大小顯示的,可以通過nameWindow(窗口名稱,cv2.WINDOW_NORMAL)命名窗口,再使用resizeWindow(窗口名稱,窗口寬度,窗口高度)縮放窗口,最后使用imshow()顯示圖像,注意三者都在同一個窗口名稱上操作。

import sys
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)

img = cv2.imread('..\\lena.jpg')
#print('img:',img)
print('type(img):',type(img))

if img is None:
    print('讀出的圖像為空')
    sys.exit(-1)
    
#原圖大小顯示
cv2.imshow('lena',img)
#縮小顯示
rows,cols = img.shape[0],img.shape[1]
cv2.namedWindow('lena-down', cv2.WINDOW_NORMAL )#cv2.WINDOW_AUTOSIZE)
cv2.resizeWindow('lena-down',(int(cols*0.5),int(rows*0.5)))
cv2.imshow('lena-down',img)
#放大顯示
cv2.namedWindow('lena-up', cv2.WINDOW_NORMAL ) 
cv2.resizeWindow('lena-up',(int(cols*1.3),int(rows*1.3)))
cv2.imshow('lena-up',img)
cv2.waitKey(0)

運行結果:

 

2.2、銷毀窗口destroyWindow()、destroyAllWindows()

在調試過程中如果顯示的窗口過多時,可以使用destroyWindow(窗口名稱)單獨關閉某個顯示窗口,也可以使用destroyAllWindows()關閉所有顯示窗口。

下面這個例子中先用destroyWindow()關閉名稱為lena-up的窗口,再用destroyAllWindows()關閉其他的所有窗口:

import sys
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)

img = cv2.imread('..\\lena.jpg')
#print('img:',img)
print('type(img):',type(img))

if img is None:
    print('讀出的圖像為空')
    sys.exit(-1)
    
#原圖大小顯示
cv2.imshow('lena',img)
#縮小顯示
rows,cols = img.shape[0],img.shape[1]
cv2.namedWindow('lena-down', cv2.WINDOW_NORMAL )#cv2.WINDOW_AUTOSIZE)
cv2.resizeWindow('lena-down',(int(cols*0.5),int(rows*0.5)))
cv2.imshow('lena-down',img)
#放大顯示
cv2.namedWindow('lena-up', cv2.WINDOW_NORMAL ) 
cv2.resizeWindow('lena-up',(int(cols*1.3),int(rows*1.3)))
cv2.imshow('lena-up',img)
cv2.waitKey(0)
cv2.destroyWindow('lena-up') #關閉lena-up窗口
cv2.waitKey(0)
cv2.destroyAllWindows()      #關閉所有顯示窗口

 

2.3、顯示封裝例程

這個例程將顯示圖像的多個操作步驟封裝在一個函數中:

dbg_is_show = False
def show_img(win_name,img,wait_time=0,img_ratio=0.15,is_show=True):
    if is_show is not True:
        return 
    rows = img.shape[0]
    cols = img.shape[1]
    cv2.namedWindow(win_name, cv2.WINDOW_NORMAL )#cv2.WINDOW_AUTOSIZE)
    cv2.resizeWindow(win_name,(int(cols*img_ratio),int(rows*img_ratio)))
    cv2.imshow(win_name,img)
    cv2.waitKey(wait_time)

 

3、寫入圖片imwrite()

imwrite()第1個位置參數是寫入的文件名稱,文件名稱的后綴決定了圖片文件的格式,第2個參數為圖像實例。

下面這個例子中將圖像分別保存在bmp,jpg格式:

import sys
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)

img = cv2.imread('..\\lena.jpg')
#print('img:',img)
print('type(img):',type(img))

if img is None:
    print('讀出的圖像為空')
    sys.exit(-1)

cv2.imwrite('lena.bmp',img)    
cv2.imwrite('lena.png',img)   
cv2.imwrite('lena.txt',img)

這個例子中倒數第3行和倒數第2行將imread()讀出的圖像實例分別寫入為bmp和jpg格式的文件,在當前工作路徑下就會看到生成了2個新的文件。最后一行故意寫入一個txt文件,該格式並不是圖像文件的格式,會拋出異常:

error: (-2:Unspecified error) could not find a writer for the specified extension in function 'cv::imwrite_'

 

 

小結:這篇文章介紹了怎么從圖片文件獲取圖像、顯示圖像、寫入圖像的操作方法。顯示圖像的方法就好像Python的print()函數,可以將圖像處理過程的中間過程顯示出來,觀察變換的效果達到調試目的。

 

 

相關閱讀:

  1. Opencv-Python教程
  2. 數據可視化~matplotlib顯示二維圖像


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM