使用opencv实现视频稳定
vidstab的Python项目详细描述
python视频稳定
使用opencv的python视频稳定。完整的searchable documentation here。
此模块包含用于视频稳定的单个类(VidStab
)。这个类基于Nghia Ho在SIMPLE VIDEO STABILIZATION USING OPENCV中提出的工作。该基金会的代码是在一个评论上的NGHIA HO的帖子由评论家用户名考拉。
Input | Output |
---|---|
内容:
安装
+ Please report issues if you install/try to install and run into problems!
安装vidstab
而不安装opencv
如果您已经在计算机上使用python绑定构建了opencv,建议您在不安装opencv的pypi版本的情况下安装vidstab
。如果您已经从环境中的源代码构建了opencv,opencv-python
python模块可能会导致问题。
下面的命令将在不包含opencv的情况下安装vidstab
。
来自PYPI
pip install vidstab
来自Github
pip install git+https://github.com/AdamSpannbauer/python_video_stab.git
安装vidstab
&opencv
vidstab
&opencv如果您还没有安装opencv,有两个选项。
- 您可以使用来自PyImageSearch、LearnOpenCV或OpenCV本身的一个很棒的在线教程来构建opencv。从源代码构建时,您有更多的选项(例如platform optimization),但有更多的责任。安装后,您可以使用上面显示的pip install命令。
- 您可以从pypi安装一个opencv的预构建发行版,作为
vidstab
的依赖项(请参阅下面的命令)
以下命令将以opencv-contrib-python
作为依赖项安装vidstab
。
来自PYPI
pip install vidstab[cv2]
来自Github
pip install -e git+https://github.com/AdamSpannbauer/python_video_stab.git#egg=vidstab[cv2]
基本用法
VidStab
类可以用作命令行脚本或在您自己的自定义python代码中使用。
使用from命令行
# Using defaults
python3 -m vidstab --input input_video.mov --output stable_video.avi
# Using a specific keypoint detector
python3 -m vidstab -i input_video.mov -o stable_video.avi -k GFTT
使用VidStab
类
fromvidstabimportVidStab# Using defaultsstabilizer=VidStab()stabilizer.stabilize(input_path='input_video.mov',output_path='stable_video.avi')# Using a specific keypoint detectorstabilizer=VidStab(kp_method='ORB')stabilizer.stabilize(input_path='input_video.mp4',output_path='stable_video.avi')# Using a specific keypoint detector and customizing keypoint parametersstabilizer=VidStab(kp_method='FAST',threshold=42,nonmaxSuppression=False)stabilizer.stabilize(input_path='input_video.mov',output_path='stable_video.avi')
高级用法
绘制帧到帧转换
fromvidstabimportVidStabimportmatplotlib.pyplotaspltstabilizer=VidStab()stabilizer.stabilize(input_path='input_video.mov',output_path='stable_video.avi')stabilizer.plot_trajectory()plt.show()stabilizer.plot_transforms()plt.show()
Trajectories | Transforms |
---|---|
使用边框
fromvidstabimportVidStabstabilizer=VidStab()# black bordersstabilizer.stabilize(input_path='input_video.mov',output_path='stable_video.avi',border_type='black')stabilizer.stabilize(input_path='input_video.mov',output_path='wide_stable_video.avi',border_type='black',border_size=100)# filled in bordersstabilizer.stabilize(input_path='input_video.mov',output_path='ref_stable_video.avi',border_type='reflect')stabilizer.stabilize(input_path='input_video.mov',output_path='rep_stable_video.avi',border_type='replicate')
^{ | ^{ |
^{ | ^{ |
---|---|
使用帧分层
fromvidstabimportVidStab,layer_overlay,layer_blend# init vid stabilizerstabilizer=VidStab()# use vidstab.layer_overlay for generating a trail effectstabilizer.stabilize(input_path=INPUT_VIDEO_PATH,output_path='trail_stable_video.avi',border_type='black',border_size=100,layer_func=layer_overlay)# create custom overlay function# here we use vidstab.layer_blend with custom alpha# layer_blend will generate a fading trail effect with some motion blurdeflayer_custom(foreground,background):returnlayer_blend(foreground,background,foreground_alpha=.8)# use custom overlay functionstabilizer.stabilize(input_path=INPUT_VIDEO_PATH,output_path='blend_stable_video.avi',border_type='black',border_size=100,layer_func=layer_custom)
^{ | ^{ |
---|---|
自动调整边框大小
fromvidstabimportVidStab,layer_overlaystabilizer=VidStab()stabilizer.stabilize(input_path=INPUT_VIDEO_PATH,output_path='auto_border_stable_video.avi',border_size='auto',# frame layering to show performance of auto sizinglayer_func=layer_overlay)
一次稳定帧
方法VidStab.stabilize_frame()
可以接受numpy
数组以允许一次稳定处理帧。
这可以使每个帧的前/后处理稳定;参见下面的示例。
最简单形式
fromvidstab.VidStabimportVidStabstabilizer=VidStab()vidcap=cv2.VideoCapture('input_video.mov')whileTrue:grabbed_frame,frame=vidcap.read()ifframeisnotNone:# Perform any pre-processing of frame before stabilization herepass# Pass frame to stabilizer even if frame is None# stabilized_frame will be an all black frame until iteration 30stabilized_frame=stabilizer.stabilize_frame(input_frame=frame,smoothing_window=30)ifstabilized_frameisNone:# There are no more frames available to stabilizebreak# Perform any post-processing of stabilized frame herepass
对象跟踪示例
importosimportcv2fromvidstabimportVidStab,layer_overlay,download_ostrich_video# Download test video to stabilizeifnotos.path.isfile("ostrich.mp4"):download_ostrich_video("ostrich.mp4")# Initialize object tracker, stabilizer, and video readerobject_tracker=cv2.TrackerCSRT_create()stabilizer=VidStab()vidcap=cv2.VideoCapture("ostrich.mp4")# Initialize bounding box for drawing rectangle around tracked objectobject_bounding_box=NonewhileTrue:grabbed_frame,frame=vidcap.read()# Pass frame to stabilizer even if frame is Nonestabilized_frame=stabilizer.stabilize_frame(input_frame=frame,border_size=50)# If stabilized_frame is None then there are no frames left to processifstabilized_frameisNone:break# Draw rectangle around tracked object if tracking has startedifobject_bounding_boxisnotNone:success,object_bounding_box=object_tracker.update(stabilized_frame)ifsuccess:(x,y,w,h)=[int(v)forvinobject_bounding_box]cv2.rectangle(stabilized_frame,(x,y),(x+w,y+h),(0,255,0),2)# Display stabilized outputcv2.imshow('Frame',stabilized_frame)key=cv2.waitKey(5)# Select ROI for tracking and begin object tracking# Non-zero frame indicates stabilization process is warmed upifstabilized_frame.sum()>0andobject_bounding_boxisNone:object_bounding_box=cv2.selectROI("Frame",stabilized_frame,fromCenter=False,showCrosshair=True)object_tracker.init(stabilized_frame,object_bounding_box)elifkey==27:breakvidcap.release()cv2.destroyAllWindows()
使用实时视频
VidStab
类还可以处理实时视频流。底层的视频阅读器是cv2.VideoCapture
(documentation)。
稳定现场视频的相关文档片段是:
Its argument can be either the device index or the name of a video file. Device index is just the number to specify which camera. Normally one camera will be connected (as in my case). So I simply pass 0 (or -1). You can select the second camera by passing 1 and so on.
VidStab.stabilize
方法的input_path
参数可以接受将直接传递给cv2.VideoCapture
的整数作为设备索引。您还可以将设备索引传递给--input
参数以供命令行使用。
直播源和视频文件之间的一个显著区别是,网络摄像头画面没有明确的终点。
结束实时视频稳定的选项是使用max_frames
参数设置最大长度,或通过按esc键或q键手动停止该过程。
如果未提供max_frames
,则无法为实时视频稳定过程显示进度条。
示例
fromvidstabimportVidStabstabilizer=VidStab()stabilizer.stabilize(input_path=0,output_path='stable_webcam.avi',max_frames=1000,playback=True)
转换文件写入和读取
生成转换并将其保存到文件中
importnumpyasnpfromvidstabimportVidStab,download_ostrich_video# Download video if neededdownload_ostrich_video(INPUT_VIDEO_PATH)# Generate transforms and save to TRANSFORMATIONS_PATH as csv (no headers)stabilizer=VidStab()stabilizer.gen_transforms(INPUT_VIDEO_PATH)np.savetxt(TRANSFORMATIONS_PATH,stabilizer.transforms,delimiter=',')
位于TRANSFORMATIONS_PATH
的文件的格式如下所示。三列代表分别为nT delta x、delta y和delta角。
-9.249733913760086068e+01,2.953221378387767970e+01,-2.875918912994855636e-02
-8.801434576214279559e+01,2.741942225927152776e+01,-2.715232319470826938e-02
从文件读取和使用转换
下面的示例读取转换文件并应用于任意视频。转换文件的格式如above section所示。
importnumpyasnpfromvidstabimportVidStab# Read in csv transform data, of form (delta x, delta y, delta angle):transforms=np.loadtxt(TRANSFORMATIONS_PATH,delimiter=',')# Create stabilizer and supply numpy array of transformsstabilizer=VidStab()stabilizer.transforms=transforms# Apply stabilizing transforms to INPUT_VIDEO_PATH and save to OUTPUT_VIDEO_PATHstabilizer.apply_transforms(INPUT_VIDEO_PATH,OUTPUT_VIDEO_PATH)