需求背景
有一個(gè)需求,要在視頻中進(jìn)行截圖,人工處理的話,就是要求選擇一些比較精彩的鏡頭進(jìn)行手工截取圖片,這就意味著,每個(gè)視頻都要自己去看一遍,然后選擇比較好的鏡頭截圖保存。
但是這種方法有很多弊端:
- 視頻有很多,一個(gè)一個(gè)地看浪費(fèi)時(shí)間和精力。
- 一個(gè)視頻里要截很多圖片,手動(dòng)截取比較慢。
- 手工截取的圖片如果不注意,會(huì)把視頻邊緣的播放器邊框、外部背景給截到,然后會(huì)有黑邊、白邊等問(wèn)題。
于是迫切需要一個(gè)自動(dòng)化的工具,能夠?qū)σ曨l進(jìn)行截圖,按照一定的規(guī)則截取,比如按照時(shí)間間隔、時(shí)間點(diǎn)、幀數(shù)等等進(jìn)行截圖,哪怕是截出來(lái)的圖片可能鏡頭不是很好,截完圖后再去人工篩選也是比較快的。
利用現(xiàn)在比較火的語(yǔ)言——Python/ target=_blank class=infotextkey>Python進(jìn)行視頻截圖
Python是比較好上手的一個(gè)編程語(yǔ)言了,而且最近一直挺火的,主要是其強(qiáng)大的類庫(kù),省去了大量的造輪子的過(guò)程,讓編程更加專注于業(yè)務(wù)本身,更加專注于實(shí)現(xiàn)你的目的。
而且Python這門(mén)語(yǔ)言不難,會(huì)點(diǎn)計(jì)算機(jī)知識(shí)、會(huì)點(diǎn)編程的應(yīng)該一學(xué)都會(huì)了。
利用Python進(jìn)行視頻截圖,是一件相對(duì)比較容易實(shí)現(xiàn)的事情,而且一旦寫(xiě)成,一勞永逸,能節(jié)省掉后期大量手工截圖花的功夫,有那個(gè)時(shí)間,喝喝茶、看看劇不是挺好嗎?
這篇文章目的也是為了照顧各種小白,讓大家更好的理解,所以介紹的會(huì)比較通俗一些。
好了,那么就讓我們開(kāi)始吧!
首先安裝Python
這個(gè)就不用多說(shuō)了吧,大家直接去Python官網(wǎng)下載安裝包。
然后安裝即可。實(shí)在不會(huì)的話,百度一下有很多安裝教程,照葫蘆畫(huà)瓢一學(xué)就會(huì)。這不是本文的核心,因此不做過(guò)多展開(kāi)了。
選擇你喜歡的IDE(開(kāi)發(fā)工具)或者編輯器寫(xiě)代碼
這里筆者比較推薦使用vscode和pycharm。
vscode是微軟推出的一款強(qiáng)大的編輯器,支持各種語(yǔ)言的開(kāi)發(fā),以及文本文檔的編寫(xiě)。其強(qiáng)大的插件機(jī)制,讓一款編輯器可以躍身成為一款強(qiáng)大的“IDE”。
pycharm是一款jetbrains公司推出的,專門(mén)用于python開(kāi)發(fā)的IDE,非常強(qiáng)大好用。
二者選其一,輕量級(jí)的選vscode會(huì)比較好。(推薦)
創(chuàng)建video_capture.py
創(chuàng)建一個(gè)py腳本文件,取名的話,你可以隨意,我這里取名為:video_capture.py
這個(gè)腳本文件就是我們要寫(xiě)代碼的地方了。
安裝opencv-python這個(gè)類庫(kù)
opencv這個(gè)類庫(kù)時(shí)需要先安裝才能使用。
按 Win + R組合鍵,調(diào)出搜索框,輸入cmd,回車打開(kāi)命令行。
在命令行中輸入下面這行內(nèi)容進(jìn)行安裝:
pip install opencv-python
但是可能會(huì)安裝失敗:
這是因?yàn)樵吹膯?wèn)題,改成阿里源就能安裝成功了!
pip install opencv-python -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
嗯,這樣就安裝成功了。
開(kāi)始寫(xiě)代碼
如果你看不懂,或者實(shí)在不想看,可以直接劃到最后,點(diǎn)擊關(guān)注@IT研究僧大師兄,私信我,發(fā)送“視頻截圖Python腳本”,我看到后會(huì)直接發(fā)給你的。
首先,導(dǎo)入cv2:
import cv2
再導(dǎo)入os庫(kù),創(chuàng)建文件要用:
import os
打開(kāi)視頻文件,這一步是獲取一個(gè)視頻截圖的對(duì)象。
cap = cv2.VideoCapture(video_path)
獲取視頻的總幀數(shù):
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
獲取視頻的幀率:
fps = cap.get(cv2.CAP_PROP_FPS)
然后就能得到視頻的總時(shí)長(zhǎng):
duration = total_frames / fps
拿到總時(shí)長(zhǎng)的目的,就是為了后面能夠根據(jù)時(shí)間來(lái)截圖。
提前創(chuàng)建好截圖保存的目錄:
try:
os.mkdir(self._output_path)except OSError:
pass
然后一個(gè)比較關(guān)鍵的地方是計(jì)算時(shí)間點(diǎn):
msec = (1000 * start_time + count * 1000 * time_interval)
其中start_time是起始時(shí)間的秒數(shù),time_interval是時(shí)間間隔的描述,這個(gè)用來(lái)每隔多少秒進(jìn)行截圖。
計(jì)算得到的msec就是視頻時(shí)間點(diǎn)的毫秒數(shù)了,然后使用這個(gè)時(shí)間設(shè)置視頻的時(shí)間位置:
(1000 * self._start_time + count * 1000 * self._time_interval)
這個(gè)函數(shù),就是把視頻的拉到指定時(shí)間的位置,就和你自己在播放器上拖動(dòng)視頻的進(jìn)度條一樣。
然后讀取視頻的這一幀圖片。
success, image = cap.read()
返回值success是bool值,true或者false,true就表示讀取成功,false就是失敗。
返回值image就是這個(gè)時(shí)間點(diǎn)的圖片了。
然后就是將這個(gè)圖片進(jìn)行保存,存儲(chǔ)在指定的路徑中。
cv2.imwrite(out_path, image, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
out_path就是要存儲(chǔ)的路徑+文件名,image是當(dāng)前截取的這張圖片,后面的參數(shù)是設(shè)置圖片質(zhì)量,這個(gè)設(shè)置100就行,最高質(zhì)量。
這就完成截取圖片了。
簡(jiǎn)單嗎?
其實(shí)簡(jiǎn)單來(lái)說(shuō),就是分三步:
- 設(shè)置視頻時(shí)間點(diǎn)。
- 讀取圖片。
- 保存圖片。
是非常簡(jiǎn)單了。這樣子,只要加上相應(yīng)的循環(huán)控制條件,從start_time循環(huán)到end_time,然后每一個(gè)時(shí)間間隔time_interval截取一張圖,這樣就能對(duì)視頻按時(shí)間間隔截取批量的圖片了。
擴(kuò)展實(shí)現(xiàn):獲取指定時(shí)間點(diǎn)的圖片
這個(gè)可以想象一下,只要給出視頻的小時(shí)數(shù)、分鐘數(shù)、秒數(shù),比如這種格式:
01:31:40
這就意味著要截取一小時(shí)三十一分四十秒處的圖片。
然后將這個(gè)時(shí)間格式轉(zhuǎn)化為毫秒數(shù)msec,然后通過(guò)
cap.set(cv2.CAP_PROP_POS_MSEC, msec)
設(shè)置視頻的時(shí)間點(diǎn),然后進(jìn)行讀取、保存就ok了。
總結(jié)
然后通過(guò)這個(gè)就能夠進(jìn)行一些額外的擴(kuò)展,比如獲取指定時(shí)間范圍內(nèi)的視頻截圖?
只要制定開(kāi)始時(shí)間start_time,截止時(shí)間end_time,然后對(duì)這個(gè)范圍內(nèi)按照時(shí)間間隔進(jìn)行截圖,就ok了。
希望能給你們啟發(fā)!






