Python 基于 OpenCV 視覺圖像處理實(shí)戰(zhàn) 之 OpenCV 視頻圖像處理基礎(chǔ)操作 之 視頻捕獲/存儲/提取/合成/合并
目錄
Python 基于 OpenCV 視覺圖像處理實(shí)戰(zhàn) 之 OpenCV 視頻圖像處理基礎(chǔ)操作 之 視頻捕獲/存儲/提取/合成/合并
一、簡單介紹
二、視頻處理流程和原理
三、視頻的捕獲和存儲
四、提取視頻中的某些幀
五、將圖片合成為視頻
六、多個(gè)視頻合并
一、簡單介紹
Python是一種跨平臺的計(jì)算機(jī)程序設(shè)計(jì)語言。是一種面向?qū)ο蟮膭?dòng)態(tài)類型語言,最初被設(shè)計(jì)用于編寫自動(dòng)化腳本(shell),隨著版本的不斷更新和語言新功能的添加,越多被用于獨(dú)立的、大型項(xiàng)目的開發(fā)。Python是一種解釋型腳本語言,可以應(yīng)用于以下領(lǐng)域: Web 和 Internet開發(fā)、科學(xué)計(jì)算和統(tǒng)計(jì)、人工智能、教育、桌面界面開發(fā)、軟件開發(fā)、后端開發(fā)、網(wǎng)絡(luò)爬蟲。
這里使用 Python? 基于 OpenCV 進(jìn)行視覺圖像處理,......
二、視頻處理流程和原理
視頻處理的基本原理涉及到圖像處理和計(jì)算機(jī)視覺領(lǐng)域的很多概念和算法。在處理視頻時(shí),常見的算法包括幀間差分、光流法、背景建模、物體檢測和跟蹤等。這些算法的原理涉及到像素級別的操作、特征提取、模型訓(xùn)練等。
視頻有各種格式,比如AVI和MP4等,在播放視頻時(shí)需要編解碼,不同的播放器都有自己的編解碼器。OpenCV目前對于AVI和MP4讀取正常,但是有大小限制,不能超過2GB。OpenCV集成了視頻處理的各種函數(shù),處理視頻的流程就是讀取完一段視頻后將視頻切分成一張張圖片,對視頻處理基本上是對圖像本身處理的一個(gè)遍歷。另外,基于視頻流可以做出各種效果,比如視頻追蹤、計(jì)算視頻幀間處理的效果等,主要應(yīng)用于圖像目標(biāo)檢測領(lǐng)域。
通過對比相鄰幀間的圖像差異,可以計(jì)算出圖像中的運(yùn)動(dòng)目標(biāo)。
- 物體檢測:首先使用目標(biāo)檢測算法(如Haar級聯(lián)檢測器、YOLO、Faster R-CNN等)在每一幀中檢測出感興趣的目標(biāo)物體,這些算法通常會(huì)使用預(yù)訓(xùn)練好的模型來識別目標(biāo)。
- 物體跟蹤:一旦檢測到目標(biāo),跟蹤算法會(huì)跟蹤目標(biāo)物體在連續(xù)幀中的位置,常見的跟蹤算法包括基于卡爾曼濾波、均值漂移、核相關(guān)濾波等。
OpenCV 提供了一些基本的流程,下面是一個(gè)簡要的概述:
視頻捕獲(Video Capture):
- 首先,需要使用 OpenCV 的
cv2.VideoCapture()
函數(shù)打開視頻文件或者連接到攝像頭。- 這個(gè)函數(shù)返回一個(gè)
VideoCapture
對象,你可以使用它來逐幀讀取視頻。逐幀處理(Frame Processing):
- 使用
VideoCapture
對象的read()
方法逐幀讀取視頻。- 對于每一幀,你可以應(yīng)用圖像處理或計(jì)算機(jī)視覺算法。
圖像處理和計(jì)算機(jī)視覺算法:
- OpenCV 提供了豐富的圖像處理和計(jì)算機(jī)視覺函數(shù),比如圖像濾波、邊緣檢測、目標(biāo)檢測、跟蹤等。
- 你可以根據(jù)你的需求選擇合適的函數(shù)來處理每一幀,例如使用
cv2.cvtColor()
進(jìn)行顏色空間轉(zhuǎn)換、cv2.Canny()
進(jìn)行邊緣檢測、cv2.findContours()
進(jìn)行輪廓檢測等。顯示處理后的幀(Display Processed Frames):
- 處理后的幀可以通過
cv2.imshow()
顯示出來,也可以保存為視頻文件。- 如果你在處理視頻時(shí)想要實(shí)時(shí)顯示處理后的幀,可以使用
cv2.imshow()
和cv2.waitKey()
結(jié)合起來。釋放資源(Release Resources):
- 在處理完所有幀后,記得釋放資源,關(guān)閉視頻文件或釋放攝像頭。
三、視頻的捕獲和存儲
視頻的讀取可以通過讀取已經(jīng)存儲好的視頻??梢酝ㄟ^打開Camera攝像頭讀取視頻圖像。OpenCV中獲取攝像頭視頻使用VideoCapture類,其構(gòu)造參數(shù)為攝像頭的Index,一般的筆記本計(jì)算機(jī)只有一個(gè)攝像頭,因此其Index一般為0。獲取視頻屬性(碼率\尺寸)使用VideoCapture的get()方法。
將視頻幀寫入文件使用VideoWriter類,其構(gòu)造參數(shù)分別為寫入的文件路徑名、編碼格式、幀率及視頻尺寸,可以通過VideoCapture獲取。
當(dāng)使用 OpenCV 處理視頻時(shí),有幾個(gè)關(guān)鍵函數(shù)在代碼中被頻繁使用。下面是其中一些函數(shù)的簡要說明:
cv2.VideoCapture():
- 這個(gè)函數(shù)用于從視頻文件或者攝像頭中讀取視頻流。
- 參數(shù)可以是視頻文件的路徑,也可以是攝像頭的索引(通常為 0 表示默認(rèn)攝像頭)。
- 返回一個(gè) VideoCapture 對象,可以用來逐幀讀取視頻。
cv2.VideoWriter():
- 這個(gè)函數(shù)用于創(chuàng)建一個(gè)用于保存視頻的 VideoWriter 對象。
- 參數(shù)包括輸出視頻文件的名稱、視頻編碼器的四字符編碼(fourcc)、幀率(fps)、視頻幀大小等。
- 返回一個(gè) VideoWriter 對象,可以用來逐幀寫入視頻。
cv2.putText():
- 這個(gè)函數(shù)用于在圖像上繪制文本。
- 參數(shù)包括輸入圖像、要繪制的文本、文本位置、字體、字體大小、顏色、線條粗細(xì)等。
import cv2
def vedioCaptureWrite(saveName):
"""
視頻捕捉與保存
:param saveName: 類似 output.avi
:return:
"""
# 打開攝像頭
cap = cv2.VideoCapture(0)
# 定義視頻編碼器
fourcc = cv2.VideoWriter_fourcc(*'XVID')
# 創(chuàng)建 VideoWriter 對象,用于保存視頻
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
# 循環(huán)讀取攝像頭幀
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 在視頻上繪制一個(gè)簡單的示例文本
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, 'Recording...', (10, 50), font, 1, (0, 255, 255), 2, cv2.LINE_AA)
# 寫入幀到輸出視頻
out.write(frame)
# 顯示幀
cv2.imshow('frame', frame)
# 按 'q' 鍵退出循環(huán)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 釋放資源
cap.release()
out.release()
cv2.destroyAllWindows()
四、提取視頻中的某些幀
視頻可以視為連續(xù)幀圖像的集合,可以對圖像的幀進(jìn)行計(jì)數(shù),也可以通過視頻的時(shí)間來提取視頻中的某些幀。
當(dāng)從視頻中提取特定幀時(shí),有幾個(gè)關(guān)鍵函數(shù)在代碼中被頻繁使用。下面是其中一些函數(shù)的簡要說明:
cv2.VideoCapture():
- 這個(gè)函數(shù)用于從視頻文件中讀取視頻流。
- 參數(shù)可以是視頻文件的路徑,也可以是攝像頭的索引(通常為 0 表示默認(rèn)攝像頭)。
- 返回一個(gè) VideoCapture 對象,可以用來逐幀讀取視頻。
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_index):
- 這個(gè)方法用于設(shè)置視頻幀的位置。
- 第一個(gè)參數(shù)是幀的索引位置,第二個(gè)參數(shù)是要設(shè)置的幀索引。
- 這個(gè)方法可以讓你定位到視頻的特定幀,以便讀取或處理。
cv2.imwrite():
- 這個(gè)函數(shù)用于將圖像保存為文件。
- 第一個(gè)參數(shù)是輸出文件的路徑,第二個(gè)參數(shù)是要保存的圖像數(shù)組。
- 支持的圖像格式包括 JPEG、PNG、BMP 等。
cap.read():
- 這個(gè)方法用于逐幀讀取視頻。
- 返回一個(gè)布爾值和幀。布爾值表示幀是否成功讀取,幀是一個(gè) NumPy 數(shù)組,包含當(dāng)前讀取的幀圖像的像素值。
import cv2
def videoExtraction(videoName):
"""
提取視頻中的某一幀保存為圖片
:param videoName: 類似 TwoPeopleRunning.mp4
:return:
"""
# 打開視頻文件
cap = cv2.VideoCapture(videoName)
# 檢查視頻是否成功打開
if not cap.isOpened():
print("Error: Unable to open video.")
exit()
# 選擇要提取的幀索引
frame_index = 100 # 例如,提取第 100 幀
# 設(shè)置視頻幀索引
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_index)
# 讀取幀
ret, frame = cap.read()
# 檢查幀是否成功讀取
if not ret:
print("Error: Unable to read frame.")
exit()
# 保存幀為圖像文件
cv2.imwrite('Images/videoExtraction.jpg', frame)
# 關(guān)閉視頻文件
cap.release()
print(f"Frame {frame_index} extracted and saved as output_frame.jpg")
五、將圖片合成為視頻
將圖片合成為視頻意味著將一系列圖片按照一定的順序和幀率組合成視頻文件。
當(dāng)將圖片合成為視頻時(shí),有幾個(gè)關(guān)鍵函數(shù)在代碼中被頻繁使用。下面是其中一些函數(shù)的簡要說明:
cv2.VideoWriter():
- 這個(gè)函數(shù)用于創(chuàng)建一個(gè)用于保存視頻的 VideoWriter 對象。
- 參數(shù)包括輸出視頻文件的名稱、視頻編碼器的四字符編碼(fourcc)、幀率(fps)、視頻幀大小等。
- 返回一個(gè) VideoWriter 對象,可以用來逐幀寫入視頻。
cv2.imread():
- 這個(gè)函數(shù)用于從圖像文件中讀取圖像。
- 參數(shù)是圖像文件的路徑。
- 返回一個(gè) NumPy 數(shù)組,包含圖像的像素值。
cv2.imwrite():
- 這個(gè)函數(shù)用于將圖像保存為文件。
- 第一個(gè)參數(shù)是輸出文件的路徑,第二個(gè)參數(shù)是要保存的圖像數(shù)組。
- 支持的圖像格式包括 JPEG、PNG、BMP 等。
os.listdir():
- 這個(gè)函數(shù)用于獲取指定路徑下的所有文件和文件夾的名稱。
- 參數(shù)是要列出的目錄的路徑。
- 返回一個(gè)包含目錄中所有條目的列表。
os.path.join():
- 這個(gè)函數(shù)用于將多個(gè)路徑組合成一個(gè)路徑。
- 參數(shù)是要組合的路徑元素。
- 返回組合后的路徑字符串。
os.path.isfile():
- 這個(gè)函數(shù)用于檢查路徑是否是一個(gè)文件。
- 參數(shù)是要檢查的路徑。
- 如果路徑指向文件,則返回 True,否則返回 False。
import cv2
import os
def imagesCompositingVideo(imageFolder, frame):
"""
圖片合成圖片
:param imageFolder: 圖片文件夾,例如 'Images'
:param frame: 每秒多少幀,例如 30幀每秒,1幀每秒
:return:
"""
# 圖片所在文件夾
images_folder = imageFolder
# 讀取文件夾中的所有圖片文件名
image_files = [f for f in os.listdir(images_folder) if os.path.isfile(os.path.join(images_folder, f))]
# 指定輸出視頻文件名
output_video = 'Videos/imagesCompositingVideo.mp4'
# 定義視頻編碼器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 獲取第一張圖片的尺寸
first_image = cv2.imread(os.path.join(images_folder, image_files[0]))
height, width, _ = first_image.shape
# 創(chuàng)建 VideoWriter 對象
out = cv2.VideoWriter(output_video, fourcc, frame, (width, height))
# 逐張讀取圖片并寫入視頻
for image_file in image_files:
image_path = os.path.join(images_folder, image_file)
img = cv2.imread(image_path)
out.write(img)
# 釋放資源
out.release()
imagesCompositingVideo()
六、多個(gè)視頻合并
多個(gè)視頻合并是指將多個(gè)視頻文件合并成一個(gè)視頻文件的過程。在這個(gè)過程中,多個(gè)視頻文件的內(nèi)容會(huì)按照一定的順序連接起來,形成一個(gè)新的視頻文件。合并多個(gè)視頻可以用于將不同的視頻片段拼接成一個(gè)完整的視頻,或者將多個(gè)視頻源合并為一個(gè)視頻文件。
通常,多個(gè)視頻合并可以分為兩種情況:
-
簡單拼接:將多個(gè)視頻按照順序連接在一起,形成一個(gè)長視頻。這種合并方式不對視頻進(jìn)行任何處理,只是將它們連接起來。
-
混流合并:將多個(gè)視頻文件進(jìn)行混流,即將它們的視頻流和音頻流合并到一個(gè)視頻文件中。這種合并方式通常需要對視頻進(jìn)行解碼、編輯和編碼等操作。
在實(shí)現(xiàn)多個(gè)視頻合并時(shí),可以使用視頻編輯軟件(如Adobe Premiere、Final Cut Pro等)或編程語言中的相應(yīng)庫(如OpenCV、FFmpeg等)來完成。
將兩個(gè)視頻文件合并為一個(gè)視頻文件。下面是關(guān)鍵函數(shù)的簡要說明:
cv2.VideoCapture():
- 這個(gè)函數(shù)用于從視頻文件中讀取視頻流。
- 參數(shù)可以是視頻文件的路徑,也可以是攝像頭的索引(通常為 0 表示默認(rèn)攝像頭)。
- 返回一個(gè) VideoCapture 對象,可以用來逐幀讀取視頻。
cv2.VideoWriter():
- 這個(gè)函數(shù)用于創(chuàng)建一個(gè)用于保存視頻的 VideoWriter 對象。
- 參數(shù)包括輸出視頻文件的名稱、視頻編碼器的四字符編碼(fourcc)、幀率(fps)、視頻幀大小等。
- 返回一個(gè) VideoWriter 對象,可以用來逐幀寫入視頻。
cap.get():
- 這個(gè)方法用于獲取視頻的屬性,如幀率、寬度、高度等。
- 參數(shù)是屬性的標(biāo)識符,比如
cv2.CAP_PROP_FPS
用于獲取幀率。- 返回屬性的值。
cap.isOpened():
- 這個(gè)方法用于檢查視頻是否成功打開。
- 如果視頻成功打開,則返回 True;否則返回 False。
cap.read():
- 這個(gè)方法用于逐幀讀取視頻。
- 返回一個(gè)布爾值和幀。布爾值表示幀是否成功讀取,幀是一個(gè) NumPy 數(shù)組,包含當(dāng)前讀取的幀圖像的像素值。
out.write():
- 這個(gè)方法用于將幀寫入到視頻文件中。
- 參數(shù)是要寫入的幀圖像。
- 每次調(diào)用這個(gè)方法都會(huì)將一幀圖像寫入到輸出視頻文件中。
cap.release():文章來源:http://www.zghlxwxcb.cn/news/detail-846247.html
- 這個(gè)方法用于釋放 VideoCapture 對象占用的資源。
- 調(diào)用這個(gè)方法后,你就不能再使用這個(gè) VideoCapture 對象了。
out.release():文章來源地址http://www.zghlxwxcb.cn/news/detail-846247.html
- 這個(gè)方法用于釋放 VideoWriter 對象占用的資源。
- 調(diào)用這個(gè)方法后,你就不能再使用這個(gè) VideoWriter 對象了。
import cv2
def mergeVideo(videoName1, videoName2):
"""
合并視頻
:param videoName1: 視頻名稱,類似 'Videos/CatRun.mp4'
:param videoName2: 視頻名稱,類似 'Videos/TwoPeopleRunning.mp4'
:return:
"""
# 打開第一個(gè)視頻文件
cap1 = cv2.VideoCapture(videoName1)
# 打開第二個(gè)視頻文件
cap2 = cv2.VideoCapture(videoName2)
# 獲取視頻信息
fps = int(cap1.get(cv2.CAP_PROP_FPS))
width = int(cap1.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 定義視頻編碼器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 創(chuàng)建 VideoWriter 對象
out = cv2.VideoWriter('Videos/mergeVideo.mp4', fourcc, fps, (width, height))
# 逐幀讀取并寫入第一個(gè)視頻文件
while cap1.isOpened():
ret, frame = cap1.read()
if not ret:
break
out.write(frame)
# 逐幀讀取并寫入第二個(gè)視頻文件
while cap2.isOpened():
ret, frame = cap2.read()
if not ret:
break
out.write(frame)
# 釋放資源
cap1.release()
cap2.release()
out.release()
到了這里,關(guān)于Python 基于 OpenCV 視覺圖像處理實(shí)戰(zhàn) 之 OpenCV 視頻圖像處理基礎(chǔ)操作 之 視頻捕獲/存儲/提取/合成/合并的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!