生活随笔
收集整理的這篇文章主要介紹了
基于python-opencv和PIL的截取视频区域生成 GIF 动图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 前言
- 用`opencv`讀取視頻
- 截取要生成gif的區(qū)域
- 播放區(qū)域視頻并選擇開始幀和結束幀
- 存儲區(qū)域截圖并用`PIL.Image`生成gif文件
- demo源碼:
- 實現效果:
前言
? 很多時候,我們想在文章中加入一些錄屏的視頻文件,可是一般都是太大不支持上傳。gif無疑是更好的選擇,可是市面上的軟件要么收費,不收費的又大多都帶水印。
? 于是就有了這篇文章,我們自己寫一個可截取視頻區(qū)域并轉換成gif文件的demo。
import cv2
as cv
video_path
= r'./PCA_Program.mp4'
cap
= cv
.VideoCapture
(video_path
)
while True:sucess
, frame
= cap
.read
()cv
.imshow
('frame', frame
)key
=cv
.waitKey
(10)if key
== 27:cv
.destroyAllWindows
()break
? 上面這段程序可以打開并播放我們指定路徑的視頻。
def on_EVENT_LBUTTON(event
, x
, y
, flags
, param
): global WN
, ES pic
= copy
.deepcopy
(image
)if event
== cv
.EVENT_LBUTTONDOWN
:WN
= (x
, y
)cv
.circle
(image
, WN
, 2, (0, 0, 255), 2)cv
.imshow
('image', image
)elif event
== cv
.EVENT_MOUSEMOVE
and (flags
& cv
.EVENT_FLAG_LBUTTON
):cv
.imshow
('image', image
)elif event
== cv
.EVENT_LBUTTONUP
:ES
= (x
, y
)cv
.rectangle
(image
, WN
, ES
, (0, 0, 255), 2)cv
.imshow
('image', image
)c
= cv
.waitKey
(0)if c
== 27:cv
.destroyAllWindows
()coord
.append
(WN
)coord
.append
(ES
)print(WN
, ES
)pic
= pic
[coord
[0][1]:coord
[1][1], coord
[0][0]:coord
[1][0]]cv
.imshow
('pic', pic
)cv
.waitKey
(2000)cv
.imshow
('image', image
)
cv
.setMouseCallback
("image", on_EVENT_LBUTTON
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
? 上述代碼可實現視頻感興趣區(qū)域的截取,輸入為播放視頻時,截取的那一幀圖像,我們對該圖像進行生成gif區(qū)域的截取。
gifs
= []
cap
= cv
.VideoCapture
(video_path
)
for i
in range(total_frames
):sucess
, frame
= cap
.read
()single_frame
= frame
[coord
[0][1]:coord
[1][1], coord
[0][0]:coord
[1][0]]cv
.imshow
('frame', single_frame
)c
= cv
.waitKey
(1)if c
== ord('s'): start
= i
elif c
== ord('e'): end
= icv
.destroyAllWindows
()breakelif i
== total_frames
- 1: end
= total_frames cv
.destroyAllWindows
()
上述代碼實現了開始幀和結束幀的選擇,以上準備工作就緒后,我們就可以開始gif的生成工作了。
-
存儲區(qū)域截圖并用PIL.Image生成gif文件
from PIL
import Image
print('開始抽幀...')
cap
= cv
.VideoCapture
(video_path
)
for i
in range(total_frames
):sucess
, frame
= cap
.read
()single_frame
= frame
[coord
[0][1]:coord
[1][1], coord
[0][0]:coord
[1][0]]resizeimgAR
= cv
.resize
(single_frame
, None, fx
=0.5, fy
=0.5, interpolation
=cv
.INTER_AREA
)frames
= Image
.fromarray
(resizeimgAR
)if start
<= i
<= end
:gifs
.append
(frames
)
print('開始生成gif...')
gifs
[0].save
(r'./PCA.gif', format='GIF', append_images
=gifs
[1::10],save_all
=True, duration
=1, loop
=0)
print('gif生成成功...')
"""
作者:魚香肉絲蓋飯
日期:2022年04月01日
""""""
程序運行后,會直接播放視頻
按空格鍵后,會停留在當前幀,等待鼠標畫框選擇生成gif的圖像區(qū)域,顯示截取的區(qū)域
按esc鍵后會關閉當前顯示的區(qū)域,播放截取區(qū)域的視頻
此時按s鍵,即選定開始幀,按e鍵,選定結束幀
按s鍵后不按e鍵,即默認視頻最后一幀為結束幀
按e鍵或視頻播放結束后,自動生成gif到視頻目錄的同文件夾下
"""import cv2
as cv
from PIL
import Image
import copy
import os
global imagecoord
= []
def on_EVENT_LBUTTON(event
, x
, y
, flags
, param
): global WN
, ESpic
= copy
.deepcopy
(image
)if event
== cv
.EVENT_LBUTTONDOWN
:WN
= (x
, y
)cv
.circle
(image
, WN
, 2, (0, 0, 255), 2)cv
.imshow
('image', image
)elif event
== cv
.EVENT_MOUSEMOVE
and (flags
& cv
.EVENT_FLAG_LBUTTON
):cv
.imshow
('image', image
)elif event
== cv
.EVENT_LBUTTONUP
:ES
= (x
, y
)cv
.rectangle
(image
, WN
, ES
, (0, 0, 255), 2)cv
.imshow
('image', image
)c
= cv
.waitKey
(0)if c
== 27:cv
.destroyAllWindows
()coord
.append
(WN
)coord
.append
(ES
)print(WN
, ES
)pic
= pic
[coord
[0][1]:coord
[1][1], coord
[0][0]:coord
[1][0]]cv
.imshow
('pic', pic
)cv
.waitKey
(2000)video_path
= r'.\CoppeliaSim Edu - RRRR_Sim_Kintmatics - rendering_ 5 ms (40.0 ' \
r'fps) - SIMULATION RUNNING 2021-11-29 21-34-42.mp4 '
cap
= cv
.VideoCapture
(video_path
)
fps
= cap
.get
(cv
.CAP_PROP_FPS
)
total_frames
= int(cap
.get
(cv
.CAP_PROP_FRAME_COUNT
))
image_size
= (int(cap
.get
(cv
.CAP_PROP_FRAME_HEIGHT
)), int(cap
.get
(cv
.CAP_PROP_FRAME_WIDTH
)))
for i
in range(total_frames
):sucess
, frame
= cap
.read
()cv
.putText
(frame
, 'real_frames:' + str(i
), (100, 200), cv
.FONT_HERSHEY_SIMPLEX
, 1, [255, 0, 0],thickness
=3)cv
.imshow
('frame', frame
)c
= cv
.waitKey
(30)if c
== ord(' '): image
= frame
[:, :]cv
.destroyAllWindows
()break
cv
.imshow
('image', image
)
cv
.setMouseCallback
("image", on_EVENT_LBUTTON
)
cv
.waitKey
(0)
cv
.destroyAllWindows
()
gifs
= []
cap
= cv
.VideoCapture
(video_path
)
for i
in range(total_frames
):sucess
, frame
= cap
.read
()single_frame
= frame
[coord
[0][1]:coord
[1][1], coord
[0][0]:coord
[1][0]]cv
.imshow
('frame', single_frame
)c
= cv
.waitKey
(50)if c
== ord('s'):start
= i
elif c
== ord('e'):end
= icv
.destroyAllWindows
()breakelif i
== total_frames
- 1:end
= total_framescv
.destroyAllWindows
()print('開始抽幀...')
cap
= cv
.VideoCapture
(video_path
)
for i
in range(total_frames
):sucess
, frame
= cap
.read
()single_frame
= frame
[coord
[0][1]:coord
[1][1], coord
[0][0]:coord
[1][0]]resizeimgAR
= cv
.resize
(single_frame
, None, fx
=0.8, fy
=0.8, interpolation
=cv
.INTER_AREA
)frames
= Image
.fromarray
(resizeimgAR
)if start
<= i
<= end
:gifs
.append
(frames
)
print('開始生成gif...')
gifs
[0].save
(r'.\CoppeliaSim Edu - RRRR_Sim_Kintmatics - rendering_ 5 ms (40.0 fps) - 'r'SIMULATION RUNNING 2021-11-29 21-34-42.gif',format='GIF', append_images
=gifs
[1::6],save_all
=True, duration
=1, loop
=0)
print('gif生成成功...')
demo源碼給大家參考,后續(xù)會持續(xù)改進邏輯,并為其設計一個UI。
這里選用視頻是本人設計的機械臂,在CoppeliaSim中的機械臂正運動學錄屏。
CSDN_video2gif演示視頻
總結
以上是生活随笔為你收集整理的基于python-opencv和PIL的截取视频区域生成 GIF 动图的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。