Created
February 25, 2017 16:15
-
-
Save residentsummer/3f2c0c26eced38be06708d1f03ad9fbb to your computer and use it in GitHub Desktop.
Script to stabilize shaky GoPro footage with ffmpeg and libvidstab
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Run without args to see usage | |
##### Configuration ##### | |
# Maximum shakiness and accuracy | |
DETECT_OPTS="shakiness=10:accuracy=15" | |
# Fish-eye correction for GoPro H3+B 16:9 Wide | |
# http://stackoverflow.com/questions/30832248/is-there-a-way-to-remove-gopro-fisheye-using-ffmpeg/40659507#40659507 | |
# I can barely see the difference, though :( | |
PRE_STAGES="lenscorrection=cx=0.5:cy=0.5:k1=-0.227:k2=-0.022" | |
# Zoom: dynamic/static/no. Dynamic may produce strange results. | |
# TRANSFORM_OPTS="smoothing=30:zoom=10:optzoom=2:zoomspeed=1:interpol=bicubic" | |
TRANSFORM_OPTS="smoothing=30:zoom=10:interpol=bicubic" | |
# TRANSFORM_OPTS="smoothing=30:interpol=bicubic" | |
# As recommended by vidstab author | |
POST_STAGES="unsharp=5:5:0.8:3:3:0.4" | |
# h.264 output options | |
VOUT_OPTS="-vcodec libx264 -preset slow -tune film -crf 18" | |
# Compare central regions of two videos side-by-side | |
SBS_PIPELINE="[0:v] crop=out_w=iw/2:x=iw/4, pad=width=iw*2 [a];[1:v] crop=out_w=iw/2:x=iw/4 [b]; [a][b] overlay=x=W/2" | |
##### Script support funcs (just skip to the next section) ##### | |
declare -a ACTIONS | |
declare -a USAGE=("Usage:") | |
add-action () { | |
ACTIONS+=($1) | |
USAGE[${#USAGE[@]}]=`echo " " $BASENAME $@` | |
} | |
usage () { | |
for ((i = 0; i < ${#USAGE[@]}; i++)); do | |
echo "${USAGE[$i]}" | |
done | |
} | |
main () { | |
action=$1 | |
shift | |
if [[ -z "${action// /}" ]]; then | |
usage && exit | |
fi | |
for a in ${ACTIONS[@]}; do | |
if [[ $action == $a ]]; then | |
$a $@ | |
exit | |
fi | |
done | |
usage | |
} | |
##### Functional part ##### | |
add-action stab-detect "<IN:video> <OUT:vectors> - analyze <video> to calculate transform <vectors>" | |
function stab-detect () { | |
VIDEO="$1" | |
VECTORS="$2" | |
ffmpeg -i "${VIDEO}" -vf "vidstabdetect=${DETECT_OPTS}:result=${VECTORS}" -f null - | |
} | |
add-action stab-transform "<IN:video> <IN:vectors> <OUT:stabilized> - produce <stabilized> version of <video> using transform <vectors>" | |
function stab-transform () { | |
VIDEO="$1" | |
VECTORS="$2" | |
STABILIZED="$3" | |
ffmpeg -i "${VIDEO}" \ | |
-vf "${PRE_STAGES},vidstabtransform=input=${VECTORS}:${TRANSFORM_OPTS},${POST_STAGES}" \ | |
${VOUT_OPTS} -acodec copy "${STABILIZED}" | |
} | |
add-action stabilize "<IN:video> <OUT:stabilized> - combined detect and transform" | |
function stabilize () { | |
VIDEO="$1" | |
STABILIZED="$2" | |
VECTORS="${VIDEO%.*}.trf" | |
stab-detect "${VIDEO}" "${VECTORS}" && \ | |
stab-transform "${VIDEO}" "${VECTORS}" "${STABILIZED}" | |
} | |
add-action compare "<IN:video1> <IN:video2> <OUT:output> - make side-by-side comparison video" | |
function compare () { | |
ffmpeg -i "$1" -i "$2" -filter_complex "${SBS_PIPELINE}" ${VOUT_OPTS} "$3" | |
} | |
main $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment