opencv mat release thrown_【OpenCV+Python】图像与视频处理入门
圖像處理入門
之前我們已經講過了OpenCV在各個平臺上安裝的方法了,從今天開始,正式進入實戰部分。首先我們需要做的就是如何讀取圖像并顯示出來,這是圖像處理的最基本的部分。
首先我們來了解幾個函數。
▼cv2.imread()
我們看一下函數的原型:
retval=cv.imread(filename[, flags])
retval為自定義名稱,filename指代需要加載的文件名,一般情況下,大多數時候,我們是直接加載文件的,所以大多時候我們直接讀入圖像就可以,但是在一些時候,我們想直接將原圖轉化為灰度圖,從而方便后期的形態學處理操作,那么這個時候第二個參數的意義就表現出來了,第二個參數屬于一個標志,它用于指定讀取圖像的方式。
總共有三種方式:
cv.IMREAD_COLOR:加載彩色圖像。圖像的任何透明度都將被忽略。這是默認標志。
cv.IMREAD_GRAYSCALE:以灰度模式加載圖像。
cv.IMREAD_UNCHANGED:加載圖像,包括alpha通道。
當然了,為了方便起見,它們也可以分別用1,0,-1進行表示。1指代原圖也就是第一個函數;0指代第二個函數代表轉為灰度圖;-1則為第三個函數。
▼cv2.imshow()
該函數用于在窗口中顯示圖像,窗口自動適合當前輸入的圖像尺寸,該函數與imread函數是相輔相成的,該函數原型為:
None=cv.imshow(winname, mat)
None為不需要填寫,不用管它,我們直接用imshow就可以,winname是指你輸出的圖像的名稱,可以自定義,但不要用中文名稱,否則會亂碼;mat則為你需要顯示的圖像。
此函數之后應是cv2.waitKey()函數,該函數顯示指定毫秒的圖像。如果不使用waitkey函數,它將不會顯示圖像。例如,waitKey(0)將無限期顯示窗口,直到任何按鍵為止(適用于圖像顯示)。waitKey(25)將顯示25毫秒的幀,此后將自動關閉顯示。
另一個函數cv2.destroyAllWindows()會銷毀我們創建的所有窗口。?如果要銷毀任何特定的窗口,請使用函數 cv.destroyWindow()在其中傳遞確切的窗口名稱作為參數。
我們現在來做一個實驗,先顯示最基本的圖像(代碼圖中都有):
現在我們改變讀入的圖像為灰度,mread函數的最后一個參數可以進行相關方面的操作,當為0時:
當為1時:
若為-1時:
現在輸出的圖像的窗口大小是固定的,那么加入我們想要調整窗口的大小,那就需要使用另一個函數,在特殊情況下,我們可以創建一個空窗口,然后再將圖像加載到該窗口。在這種情況下,可以指定窗口是否可調整大小。
這是通過功能cv.namedWindow()完成的,現在我們實驗一下:
當我們在函數后加一個0,則可以用鼠標手動調整輸出圖像的大小,這將非常方便。事實上,0對應的參數為cv2.WINDOW_NORMAL,即為自動調整圖像,我們大致了解一下相關的參數:
WINDOW_NORMAL
或WINDOW_AUTOSIZE:
WINDOW_NORMAL可以調整窗口大小,而WINDOW_AUTOSIZE會自動調整窗口大小以適合顯示的圖像(請參見imshow),并且不能手動更改窗口大小。
WINDOW_FREERATIO
或WINDOW_KEEPRATIO:
WINDOW_FREERATIO調整圖像時不考慮其比例,而WINDOW_KEEPRATIO則保持圖像比例。
WINDOW_GUI_NORMAL
或WINDOW_GUI_EXPANDED:
WINDOW_GUI_NORMAL是繪制沒有狀態欄和工具欄的窗口的舊方法,而WINDOW_GUI_EXPANDED是新的增強型GUI。默認標志==WINDOW_AUTOSIZE | WINDOW_KEEPRATIO | WINDOW_GUI_EXPANDED
假若我們想將處理之后的圖像保存起來,保存到文件夾中,那么就需要用到cv2.imwrite函數。
▼cv2.imwrite()
imwrite函數將圖像保存到指定文件。圖像格式是根據文件擴展名選擇的(擴展名列表請參見cv :: imread)。通常,使用此功能只能保存8位單通道或3通道(具有“ BGR”通道順序)圖像,但以下情況除外:
對于PNG,JPEG 2000和TIFF格式,可以保存16位無符號(CV_16U)圖像。
可以以PFM,TIFF,OpenEXR和Radiance HDR格式保存32位浮點(CV_32F)圖像;使用LogLuv高動態范圍編碼(每像素4個字節)將保存3通道(CV_32FC3)TIFF圖像。
使用此功能可以保存帶有Alpha通道的PNG圖像。為此,創建8位(或16位)4通道圖像BGRA,其中alpha通道位于最后。完全透明的像素應將alpha設置為0,完全不透明的像素應將alpha設置為255/65535。
該函數原型為:
retval=cv.imwrite(filename, img[, params])
第一個參數是文件名,第二個參數是要保存的圖像?,F在我們寫個綜合代碼:
import?numpy?as?np
import?cv2?as?cv
img?=?cv.imread('cat.jpg',?0)
cv.imshow('image',?img)
k?=?cv.waitKey(0)?&?0xff
if?k?==?27:??#?wait?for?ESC?key?to?exit
? ? cv.destroyAllWindows()
elif?k?==?ord('s'):??#?wait?for?'s'?key?to?save?and?exit
? ? cv.imwrite('cat.png',?img)
? ? cv.destroyAllWindows()
在上面的程序中,以灰度加載圖像,顯示圖像,按下鍵盤的“ s”鍵保存圖像并退出,或者按ESC鍵直接退出而不保存。我們按下s實驗:
圖像保存完畢。
那么圖像處理的入門部分算是正式結束了,這也是基礎中的基礎,后續都將非常有用。
視頻處理入門
視頻處理在OpenCV中處于極為重要的地位,目標實時跟蹤等各種實時圖像處理算法都是以視頻為基礎。
01
從相機捕獲視頻
首先我們來了解一下使用電腦自帶的相機來進行捕獲視頻。通常,我們必須使用攝像機捕獲實時流。OpenCV提供了一個非常簡單的界面來執行此操作。讓我們從相機捕獲視頻(我使用筆記本電腦上的內置網絡攝像頭),我們需要了解幾個函數:
▼cap = cv2.VideoCapture(0)
VideoCapture()中參數是0,表示打開筆記本的內置攝像頭,參數是視頻文件路徑則打開視頻,如cap = cv2.VideoCapture("../test.avi"),當然了,如果你外接的有其他的攝像頭,那就可以選用其他的參數例如1從而調用它。
▼ret,frame = cap.read()
cap.read()按幀讀取視頻,ret,frame是獲取cap.read()方法的兩個返回值。其中ret是布爾值,如果讀取幀是正確的則返回True,如果文件讀取到結尾,它的返回值就為False。frame就是每一幀的圖像,是個三維矩陣,我們都知道視頻是由一幀一幀的圖像連續組成的,OpenCV在對圖像處理時就是對每一幀的圖像進行快速處理。
▼cv2.waitkey()
waitKey()方法本身表示等待鍵盤輸入,參數是1,表示延時1ms切換到下一幀圖像,對于視頻而言;參數為0,如cv2.waitKey(0)只顯示當前幀圖像,相當于視頻暫停,;參數過大如cv2.waitKey(1000),會因為延時過久而卡頓感覺到卡頓。
c得到的是鍵盤輸入的ASCII碼,esc鍵對應的ASCII碼是27,即當按esc鍵是if條件句成立。
▼release()
調用release()釋放攝像頭,調用destroyAllWindows()關閉所有圖像窗口。
現在我們首先進行代碼實驗,之后會進行一些說明:
import?numpy?as?np
import?cv2?as?cv
cap?=?cv.VideoCapture(0)
if?not?cap.isOpened():
? ? print("Cannot?open?camera")
? ? exit()
while?True:
? ? #?Capture?frame-by-frame
? ? ret,?frame?=?cap.read()
? ? #?if?frame?is?read?correctly?ret?is?True
? ? if?not?ret:
? ? ? ? print("Can't?receive?frame?(stream?end?).?Exiting?...")
? ? ? ? break
? ? #?Our?operations?on?the?frame?come?here
? ? #?gray?=?cv.cvtColor(frame,?cv.COLOR_BGR2GRAY)
? ? #?Display?the?resulting?frame
? ? cv.imshow('frame',?gray)
? ? if?cv.waitKey(1)?==?ord('q'):
? ? ? ? break
#?When?everything?done,?release?the?capture
cap.release()
cv.destroyAllWindows()
isOpened可以確定攝像頭是否被打開,如果打開則繼續,如果未成功打開則自動退出。前面的時候我們已經講過,frame所指代的,就是攝像頭視頻的每一幀圖像,所以在顯示時,我們也是顯示每一幀。如果對每一幀圖像都進行灰度化處理,那么所顯示的視頻就是灰度化視頻,當然,關于灰度化現在還沒有講到,但是可以先做個小實驗,我們來看代碼:
import?numpy?as?np
import?cv2?as?cv
cap?=?cv.VideoCapture(0)
if?not?cap.isOpened():
? ? print("Cannot?open?camera")
? ? exit()
while?True:
? ? #?Capture?frame-by-frame
? ? ret,?frame?=?cap.read()
? ? #?if?frame?is?read?correctly?ret?is?True
? ? if?not?ret:
? ? ? ? print("Can't?receive?frame?(stream?end?).?Exiting?...")
? ? ? ? break
? ? #?Our?operations?on?the?frame?come?here
? ? gray?=?cv.cvtColor(frame,?cv.COLOR_BGR2GRAY)
? ? #?Display?the?resulting?frame
? ? cv.imshow('frame',?gray)
? ? if?cv.waitKey(1)?==?ord('q'):
? ? ? ? break
#?When?everything?done,?release?the?capture
cap.release()
cv.destroyAllWindows()
大家自己實驗,體驗一下效果。或許有的人已經發現了,我們的視頻跟實際中好像是相反的,屬于鏡像效果,我們可以取消這種效果,在這里需要介紹一個函數,后面在圖像增強部分也會介紹到:
▼cv2.flip?()
函數原型:flip(src, flipCode[, dst])
src代表輸入的圖像,我們來看一下flipCode的參數表:
現在我們加入這行代碼:
import?numpy?as?np
import?cv2?as?cv
cap?=?cv.VideoCapture(0)
if?not?cap.isOpened():
? ? print("Cannot?open?camera")
? ? exit()
while?True:
? ? #?Capture?frame-by-frame
? ? ret,?frame?=?cap.read()
? ? frame?=?cv.flip(frame,?1)
? ? #?if?frame?is?read?correctly?ret?is?True
? ? if?not?ret:
? ? ? ? print("Can't?receive?frame?(stream?end?).?Exiting?...")
? ? ? ? break
? ? #?Our?operations?on?the?frame?come?here
? ? gray?=?cv.cvtColor(frame,?cv.COLOR_BGR2GRAY)
? ? #?Display?the?resulting?frame
? ? cv.imshow('frame',?gray)
? ? if?cv.waitKey(1)?==?ord('q'):
? ? ? ? break
#?When?everything?done,?release?the?capture
cap.release()
cv.destroyAllWindows()
再實驗會發現圖像已經沒有那種鏡像效果了。
02
從文件播放視頻
從文件播放視頻與從攝像機捕獲視頻相同,只是將攝像機索引更改為視頻文件名。另外,在顯示框架時,請使用適當的時間cv.waitKey()。如果太少,則視頻將非???#xff0c;而如果太高,則視頻將變得很慢(嗯,這就是顯示慢動作的方式)。正常情況下25毫秒就可以了。
給出實例代碼:
import?cv2?as?cv
cap?=?cv.VideoCapture('test.avi')
while?cap.isOpened():
? ? ret,?frame?=?cap.read()
? ? #?if?frame?is?read?correctly?ret?is?True
? ? if?not?ret:
? ? ? ? print("Can't?receive?frame?(stream?end?).?Exiting?...")
? ? ? ? break
? ? cv.imshow('frame',?frame)
? ? if?cv.waitKey(25)?==?ord('q'):
? ? ? ? break
cap.release()
cv.destroyAllWindows()
03
保存視頻
當我們想要保存圖像的時候,這非常簡單:只需使用cv2.imwrite()。而當我們想要保存視頻的時候,需要做更多的工作。
這次我們創建一個VideoWriter對象。我們應該指定輸出文件名(例如:output.avi)。然后,我們應指定FourCC代碼(下一段中的詳細信息)。然后應傳遞每秒的幀數(fps)和幀大小。最后一個是isColor標志。如果為True,則編碼器需要彩色框,否則將與灰度框一起使用。
FourCC是一個4字節的代碼,用于指定視頻編碼器以及****??捎么a列表可在fourcc.org中找到,它取決于平臺。
在Fedora中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用XVID。MJPG可以生成大尺寸的視頻。X264提供非常小的尺寸的視頻)
在Windows中:DIVX(尚待測試和添加)。
在OSX中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。
FourCC代碼作為MJPG的`cv.VideoWriter_fourcc('M','J','P','G')or cv.VideoWriter_fourcc(*'MJPG')`傳遞。
以下代碼從攝像機捕獲,在垂直方向上翻轉每一幀,然后保存視頻:
import?numpy?as?np
import?cv2?as?cv
cap?=?cv.VideoCapture(0)
#?Define?the?codec?and?create?VideoWriter?object
fourcc?=?cv.VideoWriter_fourcc(*'XVID')
out?=?cv.VideoWriter('output.avi',?fourcc,?20.0,?(640,??480))
while?cap.isOpened():
? ? ret,?frame?=?cap.read()
? ? if?not?ret:
? ? ? ? print("Can't?receive?frame?(stream?end?).?Exiting?...")
? ? ? ? break
? ? frame?=?cv.flip(frame,?1)
? ? #?write?the?flipped?frame
? ? out.write(frame)
? ? cv.imshow('frame',?frame)
? ? if?cv.waitKey(1)?==?ord('q'):
? ? ? ? break
#?Release?everything?if?job?is?finished
cap.release()
out.release()
cv.destroyAllWindows()
大家可以自己嘗試演示效果。
視頻處理的部分基本上就結束了,以上介紹到的將是以后學習中非常重要的基礎。而事實上,OpenCV中對于視頻的處理也有更多的操作,現在介紹最后一個函數:
▼VideoCapture.get()
由于前面我們已經指定cap = cv.VideoCapture(0),所以調用此函數只需用cap.get(),get中將傳入參數,給出參數表:
共有18個參數,而至于相關的代碼,請大家自己實驗,可以使用print函數輸出視頻的詳細信息。
掃碼入群掃碼添加管理員微信加入“電子產品世界”粉絲交流群
↓↓↓↓點擊,查看更多新聞
總結
以上是生活随笔為你收集整理的opencv mat release thrown_【OpenCV+Python】图像与视频处理入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bat小游戏代码大全_Python打砖块
- 下一篇: sap权限激活_宅出职场含金量!SAP