一、學習目標
- 了解圖片的結構屬性
- 了解如何捕獲視頻
- 了解waitkey的使用方法
目錄
[python opencv 計算機視覺零基礎到實戰] 一、opencv的helloworld
[【python opencv 計算機視覺零基礎到實戰】二、 opencv文件格式與攝像頭讀取] 一、opencv的helloworld
[[python opencv 計算機視覺零基礎到實戰] 三、numpy與圖像編輯] 一、opencv的helloworld
[[python opencv 計算機視覺零基礎到實戰] 四、了解色彩空間及其詳解] 一、opencv的helloworld
[[python opencv 計算機視覺零基礎到實戰] 五、對象追蹤] 一、opencv的helloworld
二、了解opencv的圖像屬性
2.1 圖像的屬性
在我們獲取到圖像后,可以獲取到圖像的大小、類型以及通道等信息;通道指的是RGB這三個顏色通道,一幅完整的圖像是由單獨的紅色圖像、單獨的綠色圖像以及單獨的藍色圖像組成;一幅圖像若綠色通道沒有,或者說關閉,它將會偏向其它兩個顏色,同理,若其它顏色通道關閉后亦是如此。
我們可以操作這些通道信息,完成對圖像的編輯。這三個通道的單獨值范圍都是0-255,顯示方式如單獨的紅色則是(255,0,0),單獨的綠色是(0,255,0)單獨的藍色則是(0,0,255),這些值對應一種數據類型uint8,表示取值范圍就是0-255.
2.2 查看圖像的寬高通道
那如何獲取到圖像的這些屬性呢?在OpenCV中獲取這些信息是十分簡單的。首先我們可以使用shape獲取圖像的長寬以及通道個數。如下代碼:
import cv2img = cv2.imread(r'C:\Users\mx\Desktop\1.jpg')
cv2.namedWindow("Image",cv2.WINDOW_NORMAL)
cv2.destroyWindow("Image")
cv2.imshow("Image", img)
print(img.shape)
以上代碼中除了最后一行代碼,其余都是上一節的內容,最后一行代碼調用了讀取到的img圖片文件的shape屬性。shape屬性是img圖片的長寬和通道,當使用該屬性時將會得到長寬和通道屬性。結果如下:
在顯示的結果中可以看到,該值為1080、1620與3,其中長是1080,寬是1620,通道數是3。我們可以查看該圖片屬性得到值,對比是否一致。改圖片信息如下:
2.3 查看圖像的整體大小
得到信息后,我們還可以具體查看這個圖片的具體大小。使用size屬性可以獲取到當前圖片的具體大小值。
print(img.size)
在2.2示例代碼末尾處添加以上代碼。運行代碼我們可以看到顯示的內容如下:
我們可以發現,使用size查看大小后得到了5248800,這個數值是如何計算而來呢?我們可以通過計算器計算1080*1620的數值,當然得出的結果并不是5248800,因為我們還缺少一步,乘上3個通道值,因為我們的圖片是需要有RGB三個通道的圖片構成。最終通過計算機結果得出了大小的計算公式:長 * 寬 * 通道=size。
2.4 查看圖像通道所占的位數
我們接下來可以查看一下每個通道占的位數。使用dtype屬性可以查看每個通道數據的所占位數。
import cv2img = cv2.imread(r'C:\Users\mx\Desktop\1.jpg')
cv2.namedWindow("Image",cv2.WINDOW_NORMAL)
cv2.destroyWindow("Image")
cv2.imshow("Image", img)print(img.shape)
print(img.size)
print(img.dtype)
運行代碼我們可以看到顯示的內容如下:
在顯示結果中的最后一行可以得知,所占的位數是uint8這個類型,這個類型所代表的一個數據范圍就是0-255,以后若見到了該數據類型就可以很清楚的知道其中的數據的范圍了,表示無符號的0-255這個范圍的數據。
2.4 numpy
其實我們這個讀取過來的img對象的數據類型是numpy的數據類型。numpy是一個做科學計算的數據計算包,通過numpy可以簡單的去做很多運算。我們在讀取這個圖片時所存儲的內容就是很多個0-255的數據組成的,這就是這個圖片在這里最原始的樣子。也可以說“這就是計算機所見到的圖片的樣子”,這句話并不嚴謹,但是有利于我們在這個層次去對這些圖像數據做運算處理。
三、了解視頻讀取方法
3.1 了解視頻與圖片有什么關系
其實視頻就是很多張圖片而組成的,多張圖片呈現流暢的視覺感受我們就可以叫做視頻。越流暢,畫面的視頻更新率就越高,我們打游戲時有時候會說“卡成了ppt”,這個就是指視頻更新率不夠流暢,例如fps8,指每秒有8圖片進行顯示,fps 80則是表示有每秒有80張流暢的圖片在你眼前飄過,但是你感受不出來;這種呈現出來流程的視覺效果讓我們感受不出來是在看一張張的圖片。
我們在使用pr進行視頻剪輯的時候很容易感受到這種一張張圖片,這種沒一張張圖片我們稱為每一幀。如圖:
我們每次左右移動一個幀那么就是一張圖片,流程的圖片就形成了視頻動畫。我們還有更為熟悉的在紙上畫畫,隨后波動紙張就可以形成流程的動畫效果。
其實我們可以從這個原理得到在之后課程中對視頻中圖像識別的啟示。
3.2 了解捕捉視頻的方法
要捕捉相機視頻我們需要創建一個VideoCapture對象,VideoCapture方法可以選擇相機,并且返回一個VideoCapture對象。代碼如下:
captrue = cv2.VideoCapture(0)
在VideoCapture方法中,傳入的參數為選擇相機是哪一個,0代表第一個,若你有多個相機,則可以添加其他數字進行選擇。創建相機后將返回一個值,該值可以使用isOpened方法判斷相機是否打開,若沒有打開則返回,你可以可以在里面添加提示信息:
if not capture.isOpened():exit()
我們可以逐幀的讀取視頻信息。編寫一個while循環,使用capture的read方法。read方法將會返回2個結果,一個是是否正確讀取時的布爾值,一個是幀圖像:
while(True):ret,frame=capture.read()if not ret:break
以上代碼中,ret是讀取的正確與否,frame是幀圖像。若ret不正確則會直接跳出循環。這時我們可以使用imshow函數對幀圖形進行顯示,并且由于循環每次都在同一個窗口中進行顯示,這時將會刷新顯示,代碼如下:
cv2.imshow("vedio",frame)
由于我電腦跑不動,筆記本太老,需要添加個延時,并且延時設置為3秒,3000毫秒扥估3秒:
c=cv2.waitKey (3000)
為什么要等于c呢?這時因為我需要判斷是否按下esc鍵進行退出。waitkey可以在一定時間內等待你按下鍵并且進行記錄,esc鍵的值是27,所以代碼為:
if c==27:break
整體代碼為:
import cv2capture=cv2.VideoCapture(0)
if not capture.isOpened():exit()
while(True):ret,frame=capture.read()if not ret:breakcv2.imshow("vedio",frame)c=cv2.waitKey (3000)if c==27:break
這時可以運行代碼查看效果,如果你電腦比我的更差,嗯。。。那就延時設置更高吧。運行效果如下:
本人比較害羞所以打碼了,并且由于我設備有些問題,所以出現了點不一樣的情況,正常情況會清晰的顯示出結果的。
注:文章首發于ebaina
四、總結
- 了解圖片的屬性是有3個通道,分別為紅綠藍,并且可以通過shape獲取到圖片的寬高和三個通道
- 了解了如何計算圖片的大小,是寬高乘積再乘3
- 了解了一張完整的圖片是由3個單張的紅綠藍三通道圖片組成
- 了解捕獲視頻需要創建VideoCapture對象
- 了解了選擇設備在VideoCapture方法中傳入參數進行選擇
- 了解waitkey的可以等待并且接受輸入的按鍵值