1. 程式人生 > >OpenCV(3.2)+Python(3.6)學習(基於官方API)(一)

OpenCV(3.2)+Python(3.6)學習(基於官方API)(一)

1.1 Getting Started with Images

  博主最近由於專案需求,需要學習OpenCV,在檢視並試驗了幾種語言之後決定用Python作為開發語言。剛開始學習也是各種網上找資料,但是網上的資料過於雜亂,最後還是覺得官方API最全面。所以博主梳理近期學習OpenCV官方文件的過程,並且用部落格記錄下來(官方文件的第一部分是關於opencv的安裝,這裡不做介紹,直接進入第二部分)。這篇部落格先從OpenCV官方文件第二部分(Gui Features in OpenCV)開始,在這個部分官方文件給我們介紹了三個函式。

cv2.imread()

這個函式用來讀取一副影象,第一個引數(必須傳)可以是圖片的相對路徑或者絕對路徑(如果你第一個引數傳錯,程式不會報錯,但是函式的返回值會是None),第二個引數(可選)指定你要以何種方式讀取圖片,第二引數是個列舉值它可以是:
- cv2.IMREAD_COLOR:載入一張彩色圖片,忽略它的透明度,在不傳第二個引數時,它也是預設值。
- cv2.IMREAD_GRAYSCALE:載入灰度圖。
- cv2.IMREAD_UNCHANGED:載入一張圖片包含它的alpha通道(透明度),就是原影象不做改變的載入。

提示:如果你覺得上面三個列舉值很難記你可以簡單的用1,0,-1代替。
具體請看下面的程式碼

 import numpy as np 
 import cv2

 #載入一張彩色圖片不包含alpha通道
 img = cv2.imread('demo.jpg',1)

cv2.imshow()

這個函式用來在一個視窗中顯示一幅圖片,視窗自動適配圖片的大小。
這個函式也接收兩個引數,第一個引數是要承載圖片的視窗名(字串型別),第二個引數就是我們要顯示的圖片。只要每個視窗的名字不重複,我們可以建立多個視窗。
請看下面的程式碼片段

cv2.imshow('image'
,img) cv2.waitKey(0) cv2.destroyAllWindows()

在我的環境下(windows10 x64)執行結果如下:

讀取到的圖片

下面解釋上面用到的一些函式

cv2.waitKey() 是一個鍵盤繫結函式。它的引數是一個毫秒數。這個函式等待特定的毫秒,如果在這個時間之內有按鍵按下,它就會返回相應按鍵的 ASCII 碼(int 型別),然後程式繼續執行,如果在給定的時間內沒有任何按鍵按下它會返回 255(int 型別),然後程式繼續執行。特別的,如果你傳遞一個0(或者一個負數)給這個函式,那麼它會一直等待,直到有任何按鍵按下,然後程式繼續執行。我們也可以只監視某些按鍵的按下而不是任意按鍵,這個我們在後面討論。但是有一點必須注意,cv2.imshow()函式後面必須有cv2.waitKey()函式,否則圖片不會顯示。

cv2.destroyAllWindows() 將我們建立的所有視窗全部銷燬。如果你想銷燬任何特定的視窗,請使用 cv2.destroyWindow() 函式並將特定視窗的名字作為引數傳遞進去。

提示:有時候你可以事先建立好一個視窗後面再載入圖片。在這種情況下你可以指定視窗是否可以調整大小,這要用到函式 cv2.namedWindow() 函式。預設狀態下標誌位是 cv2.WINDOW_AUTOSIZE 。但是你可以指定標誌位為 cv2.WINDOW_NORMAL ,這樣你就可以調整視窗的大小了。下表顯示都有哪些標誌位可供我們選擇。

列舉值 表示的意思
WINDOW_NORMAL 使用者可以調整視窗的大小,也可以將一個視窗從全屏視窗切換到普通視窗
WINDOW_AUTOSIZE 使用者不能改變視窗的大小,視窗的大小被所展示的圖片所約束
WINDOW_OPENGL opengl支援的視窗
WINDOW_FULLSCREEN 將視窗設定為全屏
WINDOW_FREERATIO 擴充套件圖片不考慮圖片的解析度
WINDOW_KEEPRATIO 擴充套件圖片但考慮圖片的解析度
WINDOW_GUI_EXPANDED 帶進度條和工具條
WINDOW_GUI_NORMAL 舊方法

解釋:經測試之後發現,第三個列舉值需要安裝OPENGL的支援,後5個列舉值在效果上與WINDOW_NORMAL沒有什麼區別,如果有朋友對這個特別瞭解,歡迎討論。

請看下面的程式碼

cv2.namedWindow('window_name',cv2.WINDOW_NORMAL)
cv2.imshow('window_name',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.imwrite()

這個函式用來儲存一張圖片。
第一個引數是儲存之後檔案的檔名(可以包含檔案路徑),第二個引數是你想要儲存的圖片。

cv2.imwrite('copy.png',img)

這樣會儲存一張 PNG 格式的圖片在你的工作目錄(就是跟你的.py檔案在一個目錄下)。

cv2.imwrite('..\copy.jpg',img)

這樣會儲存一張 JPG 格式的圖片在你工作目錄的上一級目錄

或者你可以直接這樣寫

cv2.imwrite('C:\Program Files\opencv\copy.bmp',img)

這樣就會在指定的位置儲存一張 BMP 圖片

注意:你總是需要指定檔案的副檔名,雖然官方文件中說不寫副檔名就會儲存一張 PNG 檔案在指定目錄,但是實際測試這麼做會報 (could not find a writer for the specified extension) 這個錯誤,告訴你指定的副檔名沒有 writer 可以寫出來,經測試主流的幾種圖片格式 (jpg,png,bmp) 都是支援的。第二點就是在你寫檔案路徑的時候注意斜線的方向。

現在我們把之前的程式碼統一起來,下面這段程式碼首先以彩色忽略透明度的模式載入一張圖片,然後顯示圖片,如果你按下 ‘s’ 鍵它會儲存圖片到指定位置後程序退出,如果按下 ‘esc’ 鍵那麼不儲存直接退出,如果按了別的鍵它會提示你,然後程式退出。

import numpy as np
import cv2

img = cv2.imread('demo.jpg',1)
cv2.imshow('image',img)
k = cv2.waitKey(0)
if( k== 27):
    cv2.destroyAllWindows()
elif( k==ord('s')):
    cv2.imwrite('copy.png',img)
    cv2.destroyAllWindows()
else:
    print('你沒有按下S或者ESC,程式退出')
    cv2.destroyAllWindows()

提示:官方文件中說如果你使用64位的機器,你必須將 k=cv2.waitKey(0) 改為k=cv2.waitKey(0) & 0xFF,但是經過我的測試不修改程式仍然可以正常執行。

Matplotlib 是python的一個繪相簿,它提供了大量的繪圖方法。在後面的文章中我們也會遇到,現在我們來學習如何用 Matplotlib 來顯示一張圖片。你可以用它來放大、儲存圖片等等。

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('demo.jpg',0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()

執行之後結果如圖

用matplotlib畫的圖

注意:在OpenCV中彩色圖片是以BGR模式載入的,但在matplotlib中是以RGB模式。所以如果用OpenCV讀取一張彩色圖片在matplotlib中將無法正常顯示。請參考這裡的討論試著理解它。