使用OpenCV實現(xiàn)逐幀獲取視頻圖片
背景
由于我要做一個深度學(xué)習(xí)方向的計算機視覺項目,需要一些數(shù)據(jù)集來進(jìn)行訓(xùn)練,我便想嘗試捕獲視頻中的圖片用來標(biāo)注。
注意事項
如果視頻中的場景單一,那么使用該視頻獲取的數(shù)據(jù)集訓(xùn)練出的模型面對其他場景的泛化能力就會受到限制。為了提高數(shù)據(jù)集的多樣性,可以采用多種不同場景的視頻,并且在獲取數(shù)據(jù)時采用大間隔捕獲的方式。采用大間隔捕獲數(shù)據(jù)的方法可以捕獲到的圖片同質(zhì)化降低,從而進(jìn)一步增加數(shù)據(jù)集的多樣性。
import os import sys from concurrent.futures import ThreadPoolExecutor import cv2 def output_img(video_path,img_dir): # 由視頻逐幀輸出圖片 # video_path: 視頻文件路徑 # img_dir: 圖片保存目錄路徑,路徑不支持中文 os.makedirs(img_dir,exist_ok=True) # img_dir:表示要創(chuàng)建的目錄路徑。 # exist_ok=True:表示如果目錄已經(jīng)存在時不拋出異常。如果將 exist_ok 設(shè)置為 True,那么如果目錄已經(jīng)存在,os.makedirs() 函數(shù)也不會報錯;如果設(shè)置為 False,則會拋出一個 FileExistsError 異常。 cv = cv2.VideoCapture(video_path) frame_count = 0 # 計數(shù)器 n = 0 # 命名計數(shù)器 while True: ret,frame = cv.read() if not ret: break frame_count += 1 if frame_count % 30 ==0: # 每隔三十幀獲取一次圖片 n += 1 img_name = "0000000{0}.jpg".format(n) img_file_path = os.path.join(img_dir,img_name) if not os.path.exists(img_file_path): sys.stdout.write("創(chuàng)建文件:"+ img_file_path + "\n") # 標(biāo)準(zhǔn)輸出流,將指定文本輸出到控制臺或其他輸出設(shè)備中 cv2.imwrite(img_file_path,frame,[cv2.IMWRITE_JPEG_QUALITY,100]) # 將圖像幀保存為jepg格式的圖像,質(zhì)量最高為100 else: sys.stderr.write("跳過:" + img_file_path + "\n") ret,frame = cv.read() def run(video_dir,img_dir): pool = ThreadPoolExecutor() # 創(chuàng)建一個線程池對象,實例化ThreadPoolExecutor類,將任務(wù)提交給線程池,線程池會自動調(diào)度線程來執(zhí)行這些任務(wù) for file in os.listdir(video_dir): if file[-4:] == ".mp4": video_file_path = os.path.join(video_dir,file) img_dir_name = os.path.join(img_dir,file[:-4]) os.makedirs(img_dir_name,exist_ok=True) pool.submit(output_img,*(video_file_path,img_dir_name)) #* 和 ** 是用于解包參數(shù)的操作符。在這種情況下,*(video_file_path, img_dir_name) # 的作用是將元組 (video_file_path, img_dir_name) 中的元素解包并作為單獨的參數(shù)傳遞給函數(shù)。 if __name__ == '__main__': run(r"E:\video",r"E:\image")
知識補充
除了上文的方法,小編還為大家整理了opencv按幀提取視頻中的圖片的相關(guān)方法,希望對大家有所幫助
方法一
import cv2 import logging # log information settings logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s') def save_image(num, image): image_path = 'D:\CODE\keras-face-recognition\jietu/{}.jpg'.format(str(num)) cv2.imwrite(image_path, image) vc = cv2.VideoCapture('1.avi') if vc.isOpened(): ret, frame = vc.read() else: ret = False count = 0 # 照片排序 frame_interval = 10 # 隔10幀取圖片 frame_interval_count = 0 while ret: ret, frame = vc.read() if frame_interval_count % frame_interval == 0: save_image(count, frame) logging.info("num:" + str(count) + ", frame: " + str(frame_interval_count)) count += 1 frame_interval_count += 1 cv2.waitKey(1) vc.release()
方法二
import cv2 import os #要提取視頻的文件名,隱藏后綴 sourceFileName='a2' #在這里把后綴接上 video_path = os.path.join("", "", sourceFileName+'.mp4') times=0 #提取視頻的頻率,每25幀提取一個 frameFrequency=25 #輸出圖片到當(dāng)前目錄vedio文件夾下 outPutDirName='vedio/'+sourceFileName+'/' if not os.path.exists(outPutDirName): #如果文件目錄不存在則創(chuàng)建目錄 os.makedirs(outPutDirName) camera = cv2.VideoCapture(video_path) while True: times+=1 res, image = camera.read() if not res: print('not res , not image') break if times%frameFrequency==0: cv2.imwrite(outPutDirName + str(times)+'.jpg', image) print(outPutDirName + str(times)+'.jpg') print('圖片提取結(jié)束') camera.release()
方法三
import cv2 import os video_path = 'D:/BaiduNetdiskDownload/DISFA/Videos_LeftCamera/LeftVideoSN032_comp.avi' # 視頻文件地址,是視頻文件 timeF = 1 # 隔timeF幀截一次圖,1表示全截 images_path = video_path.split('.', 1)[0] #.號隔開,1代表分割一次 if not os.path.exists(images_path): # 文件夾不存在則新建 os.mkdir(images_path) vc = cv2.VideoCapture(video_path) # 讀入視頻文件 c = 0 rat = 1 if vc.isOpened(): # 判斷是否正常打開 print('視頻讀取成功,正在逐幀截取...') while rat: # 循環(huán)讀取視頻幀 rat, frame = vc.read() # frame為一幀圖像,當(dāng)frame為空時,ret返回false,否則為true if(c%timeF == 0 and rat == True): # 每隔timeF幀截一次圖像 cv2.imwrite(images_path + '/' + str(c) + '.jpg',frame) c = c + 1 vc.release() print('截取完成,圖像保存在:%s' %images_path) else: print('視頻讀取失敗,請檢查文件地址')
到此這篇關(guān)于使用OpenCV實現(xiàn)逐幀獲取視頻圖片的文章就介紹到這了,更多相關(guān)OpenCV獲取視頻圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Opencv實戰(zhàn)之印章提取的實現(xiàn)
很多時候我們需要電子版的章,但有些同學(xué)并不會通過Photoshop摳圖獲取。因此本文將利用Python OpenCV來實現(xiàn)印章的提取,感興趣的可以了解一下2022-03-03Python3.7 讀取音頻根據(jù)文件名生成腳本的代碼
這篇文章主要介紹了Python3.7 讀取音頻根據(jù)文件名生成字幕腳本的方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04一個Python案例帶你掌握xpath數(shù)據(jù)解析方法
xpath解析是最常用且最便捷高效的一種解析方式,通用性強。本文將通過一個Python爬蟲案例帶你詳細(xì)了解一下xpath數(shù)據(jù)解析方法,需要的可以參考一下2022-02-02Python實現(xiàn)Linux監(jiān)控的方法
本文通過實例代碼給大家介紹了Python實現(xiàn)Linux監(jiān)控的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05