ffmpeg, convert (imagemagick) exiftool, vips and MeshLab crib sheet

Assembled by Paul Bourke
Started June 2018, ongoing ...


A small collection of helpful command lines for ffmpeg and convert (imagemagick). Certainly not trying to be comprehensive but a note to myself for things I seem to need to do regularly. Collated here to save myself digging around on-line and/or through the respective manuals. Hopefully others may find them useful also. If you think the following are incomplete, can be improved, or if you would like to add your own please drop me an email.


ffmpeg

Convert mp4 to mov.
   ffmpeg -i inputmoviename -acodec copy -vcodec copy -f mov outputmoviename
Convert frames to movie using Apple animation codec
   ffmpeg -framerate 30 -i inputframes%04d.png -vcodec qtrle outputmoviename
Convert from mov to mp4
   ffmpeg -i inputmoviename -vcodec copy -acodec copy outputmoviename
Convert from mov to mp4 using h265 compression, default preset is medium, default crf is 28
   ffmpeg -i inputmoviename -c:v libx265 -preset slow -crf 25 -acodec copy outputmoviename
Add audio to existing movie, transcoding the audio
   ffmpeg -i inputvideo.mp4 -i inputaudio.wav -c:v copy -c:a aac output.mp4
Used for making mp4 for Gear VR, this was 2015, may have changed now.
   ffmpeg -framerate 30 -i inputframename%04d.png -c:v libx264 -profile:v high 
      -crf 18 -pix_fmt yuv420p outputmoviename
Extract frames
   ffmpeg -i inputmoviename -q:v 1 -qmin 1 directoryname/outputframename%04d.tga
Extract a single frame from a particular position
   ffmpeg -ss 00:01:00 -i inputmoviename -vframes 1 -q:v 1 -qmin 1 outputimagename
Extract every N'th frame between two times
   ffmpeg -i inputmovie.mp4 -ss 00:03:00 -to 00:03:20 -vf "select='not(mod(n\,10))'" -vsync vfr -q:v 1 -qmin 1 outdirectory/%04d.jpg
Extract a time range from a movie, start and duration, or start and stop position
   ffmpeg -i inputmoviename -ss 00:00:30 -t 00:00:50 -codec copy outputmoviename
   ffmpeg -i inputmoviename -ss 00:00:30 -t0 00:01:20 -codec copy outputmoviename
Extract 16 bit from greater than 8 bit movies, eg: GH5
   ffmpeg -i inputmoviename -vf "format=pix_fmts=rgb48" directoryname/outputframename%04d.png
Extract frames and scale
   ffmpeg -i inputmoviename -vf scale=2048:1080 -q:v 1 -qmin 1 directoryname/outputframename%04d.tga
Extract frames and rotate by multiples of 90 degrees (see transpose options)
   ffmpeg -i inputmoviename -vf transpose=2 -q:v 1 -qmin 1 directoryname/outputframename%04d.tga
Build mp4 movie from frames
   ffmpeg -r 30 -start_number N -i scene%04d.tga -c:v libx265 -crf 20 outputmoviename
Build mp4 movie from frames for system that don't fully support yuv444p
   ffmpeg -r 30 -i scene%04d.jpg -c:v libx264 -crf 20 -pix_fmt yuv420p outputmoviename
   ffmpeg -r 30 -i scene%04d.png -c:v libx265 -crf 26 -tag:v hvc1 -pix_fmt yuv420p outputmoviename
Build mp4 movie from frames with all i-frames, no B or P frames
   ffmpeg -r 60 -i frames/%05d.tga -c:v libx264 -crf 23 -pix_fmt yuv420p -intra outputmoviename
Build mp4 from frames and audio
   ffmpeg -r 30 -i dirname/frame_%d.jpg -i audio.mp4 -c:a copy -c:v libx265 outputmovie.mp4
   ffmpeg -r 30 -i dirname/frame_%d.jpg -i audio.mp4 -c:a copy -c:v libx265 -crf 24 outputmovie.mp4
   ffmpeg -r 30 -i dirname/frame_%d.jpg -i audio.mp4 -c:a copy -c:v libx264 -crf 18 outputmovie.mp4
Extract audio channels
   ffmpeg -i video13.mp4 -vn -acodec copy video13.mp3
Convert and apply remap filter
   ffmpeg -i inputmoviename -i 0001_x.pgm -i 0001_y.pgm -lavfi remap outputmoviename
For missing values the chroma key colour is used, to change from green to black
    ffmpeg -i inputmovie -i x.pgm -i y.pgm -lavfi remap=fill=black outputmovie
Convert and apply cropping
   ffmpeg -i inputmoviename -filter:v "crop=out_w:out_h:x:y" outputmoviename
Movie encoding from frames, proposed for fulldome video using Watchout
   ffmpeg -threads auto -r 30 -i "inputframedirectory/inputframename%04d.png" -f vob 
      -vcodec mpeg2video -b:v 30000k -minrate 30000k -maxrate 30000k -g 15 -bf 2 -an 
      -trellis 2 "outputmoviename.m2v"
Movie encoding from frames with HAP codec, proposed for Vioso Wings fulldome playback. Ensure ffmpeg is installed "with-snappy".
   ffmpeg -r 30 -i "inputframedirectory/inputframename%04d.tga" -vcodec hap 
      -format hap -r 30 outputmoviename
Movie information.
   ffmpeg -i moviename
Scale a movie.
   ffmpeg -i inputmoviename -filter:v scale=640:480 -c:a copy outputmoviename
QuickTime movie to animated gif. (Contributed by Jordi VallverdĂș Alcover)
   ffmpeg -ss 00:00:00.000 -i input.mov -pix_fmt rgb24 -r 10 
      -s 320x240 -t 00:00:10.000 output.gif
   convert -layers Optimize output.gif output_optimized.gif
Record from webcam (Mac OSX)
   ffmpeg -f avfoundation -list_devices true -i ""
   ffmpeg -f avfoundation -framerate 30 -video_size 1280x720 
      -pixel_format rgb24 -i "0:0" out.mov
   ffmpeg -f avfoundation -framerate 30 -video_size 1280x720 -i "0:0" 
      -c:v libx264 -crf 22 out.mp4
Append two movies side by side
   ffmpeg -i inputmovie1 -i inputmovie2 
      -filter_complex "[0:v:0]pad=iw*2:ih[bg]; [bg][1:v:0]overlay=w" 
      -c:v libx264 outputmoviename
Append two movies side by side or top and bottom
   ffmpeg -i inputmovie1 -i inputmovie2 -filter_complex vstack outputmoviename
   ffmpeg -i inputmovie1 -i inputmovie2 -filter_complex hstack outputmoviename
Turn a single image into a movie of a specified length
   ffmpeg -loop 1 -i inputimagename -c:v libx264 -t 10 -pix_fmt yuv420p outputmoviename
Combine separate 5.1 channels into a single wav file
ffmpeg \
   -i Leftchannelfilename.wav \
   -i Rightchannelfilename.wav \
   -i Centerchannelfilename \
   -i LFEchannelfilename.wav \
   -i Leftsurroundchannelfilename.wav \
   -i Rghtsurroundchannelfilename.wav \
   -filter_complex \
      "[0:a][1:a][2:a][3:a][4:a][5:a]join=inputs=6:channel_layout=5.1:map=0.0-FL|1.0-FR|2.0-FC|3.0-LFE|4.0-BL|5.0-BR[a]" \
   -map "[a]" outputfilename.wav
Convert cube map YouTube videos
ffmpeg -i inputmoviename.mp4
   -vf "v360=c3x2:e:cubic:in_forder='lfrdbu':in_frot='000313',scale=3840:1920,setsar=1:1" 
   -pix_fmt yuv420p -c:v libx264 -crf 17 -c:a copy 
   outputmoviename.mp4
Unpack a downloaded 360 YouTube video and encode for Oculus
ffmpeg -y -i "virtualnature.mp4" \
   -vf "v360=c3x2:e:cubic:in_forder='lfrdbu':in_frot='000313',scale=5760x2880,setsar=1:1" \
   -ss 00:00:20 -t 00:00:40 \
   -c:v libx264 -preset slow -crf 18 -x264-params "mvrange=511" -maxrate 120M \
   -bufsize 150M -pix_fmt yuv420p -c:a aac -b:a 192k -movflags faststart \
   virtualnature_four_oculus.mp4
Add an audio file to an image so it can be uploaded to FaceBook
   ffmpeg -loop 1 -i an_image.jpg -i the_autio_filename -shortest theoutputname.mp4
Pipe ffmpeg to ffplay, for example for remap filters which ffplay doesn't support
   ffmpeg -i amovie.mp4 -i x.pgm -i y.pgm -r 30 -lavfi remap -f matroska - | ffplay -fs -r 30 -
Remove audio track
   ffmpeg -i inputmoviename -c copy -an outputmoviename

exiftool

Extract and assign colour profile
   exiftool -icc_profile -b imagefilename.jpg > theprofile.icc
   exiftool "-icc_profile<=theprofile.icc" newimagefilename.jpg
Tag as equirectangular, eg: for FaceBook
   exiftool -ProjectionType="equirectangular" imagefilename.jpg
Tag as cylindrcial panorama, eg: for faceBook
   exiftool -FullPanoWidthPixels=8192 -FullPanoHeightPixels=4096 
            -CroppedAreaLeftPixels=0 -CroppedAreaTopPixels=1195 
            -CroppedAreaImageWidthPixels=8192 -CroppedAreaImageHeightPixels=1707 
            -ProjectionType=cylindrical imagefilename.jpg

Where verical FOV = 2 atan(H pi / W), where H is the height of the panorama in pixels and W is the width. The spreadsheet for calculating the exiftool command line is provided here.


imagemagick

Resize proportionately
   convert inputfilename -resize 4096x2048 outputfilename.jpg
Rotate
   convert sourceimage -rotate 90 destinationimage
Split image into 4 pieces horizontally
   convert inputfilename -crop 4@x1 +repage output filenamemask
Resize forced
   convert inputfilename -resize 4096x2048\! outputfilename.jpg
Resize a wildcard selection of images (in place)
   mogrify -resize 50% *.jpg
Crop, supply size and origin
   convert -crop 256x256+1024+0 inputfilename.exr outputfilename.jpg
Concatenate N images horizontally
   convert inputfilename1.jpg inputfilename2.jpg ... inputfilenameN.jpg +append outputfilename.jpg
Concatenate N images vertically
   convert inputfilename1.jpg inputfilename2.jpg ... inputfilenameN.jpg -append outputfilename.jpg
Specify jpeg compression quality
    convert -quality 90 -verbose inputfilename.tga outputfilename.jpg
Create pyramidal tiff
   convert inputimagename.tif -define tiff:tile-geometry=256x256 -compress jpeg 'ptif:outputfilename.ptif'
Translate PSB to BigTiff
   convert inputimagename.psb tiff64:outputimagename.tif
Dice an image up into parts
   convert -crop 25%x25% inputimage.jpg split%2d.jpg
   convert -crop 8192x8192 inputimage.jpg split%2d.jpg
Create an animated gif.
   convert -delay 120 -loop 0 inputframesequence*.png outputfilename.gif
Convert a raw RGB file to tiff.
   convert -size WIDTHxHEIGHT -depth 16 inputfilename.rgb outputfilename.tiff
Convert a series of png files to tiff
   mogrify -format tiff *.png
Copy alpha channel from one image to another
   convert sourceimage.jpg BWmaskimage.jpg -compose copy-opacity -composite output.png
Determine (estimate) the compression used in an existing jpeg image
   identify -verbose jpegfilename
   identify -verbose jpegfilename | grep Quality

MeshLab

While most people engage with MashLab through the graphical interface, it is possible to script operations on the command line. This is accomplished through the meshlabserver. Details on different platforms may differ, for example in the location of the server, but on the Mac it might be invoked as follows:

/Applications/meshlab.app/Contents/MacOS/meshlabserver -i $1.obj -o $1_cleaned.obj -m wt -s clean.mlx

The .mlx file describes the operations to be performed, in this case clean.mlx might be

<!DOCTYPE FilterScript>
<FilterScript>
 <filter name="Remove Unreferenced Vertices"/>
 <filter name="Remove Zero Area Faces"/>
 <filter name="Remove Duplicate Vertices"/>
 <filter name="Remove Duplicate Faces"/>
 <filter name="Merge Close Vertices">
 <Param type="RichAbsPerc" description="Merging distance" 
   min="0" max="0.012423" tooltip="All the vertices that closer 
   than this threshold are merged together. Use very small values, 
   default values is 1/10000 of bounding box diagonal. " 
   name="Threshold" value="0.00012423" isxmlparam="0"/>
 </filter>
</FilterScript>
Remove unreferenced vertices
<!DOCTYPE FilterScript >
<FilterScript>
 <filter name="Remove Unreferenced Vertices"/>
</FilterScript>
Decimate a mesh
CTYPE FilterScript>
<FilterScript>
 <filter name="Simplification: Quadric Edge Collapse Decimation (with texture)">
  <Param value="1000000" name="TargetFaceNum" description="Target number of faces" 
     isxmlparam="0" tooltip="" type="RichInt"/>
  <Param value="0" name="TargetPerc" description="Percentage reduction (0..1)" 
     isxmlparam="0" tooltip="" type="RichFloat"/>
  <Param value="0.3" name="QualityThr" description="Quality threshold" 
     isxmlparam="0" tooltip="" type="RichFloat"/>
  <Param value="1" name="Extratcoordw" description="Texture Weight" 
     isxmlparam="0" tooltip="" type="RichFloat"/>
  <Param value="false" name="PreserveBoundary" description="Preserve Boundary of the mesh" 
     isxmlparam="0" tooltip="" type="RichBool"/>
  <Param value="1" name="BoundaryWeight" description="Boundary Preserving Weight" 
     isxmlparam="0" tooltip="" type="RichFloat"/>
  <Param value="true" name="OptimalPlacement" description="Optimal position of simplified vertices" 
     isxmlparam="0" tooltip="" type="RichBool"/v
  <Param value="true" name="PreserveNormal" description="Preserve Normal" 
     isxmlparam="0" tooltip="" type="RichBool"/>
  <Param value="true" name="PlanarQuadric" description="Planar Simplification" 
     isxmlparam="0" tooltip="" type="RichBool"/>
  <Param value="false" name="Selected" description="Simplify only selected faces" 
     isxmlparam="0" tooltip="" type="RichBool"/>
 </filter>
</FilterScript>
Remove zero area faces
<!DOCTYPE FilterScript>
<FilterScript>
 <filter name="Remove Zero Area Faces"/>
</FilterScript>

Brief note on smoothing meshes in Meshlab

krpano

Split a file into chunks with a maximum specified pixel size.
   krpanotools maketiles 420000.tif %h_%v.psb 100000
Resize a large image
   krpanotools maketiles 420000.tif resized.psb -resize=300000x100000 -keepaspect

vips

Change from 16 to 8 bit
   vips colourspace sourceimage destinationimage srgb
Join two image together
   vips join sourceimage1 sourceimage2 destinationimage horizontal
   vips join sourceimage1 sourceimage2 destinationimage vertical
Resize an image by a scale factor, say 1/10
   vips resize soureimage destinationimage 0.1
Crop an image given top left position and width and height
   vips crop soureimage destinationimage 100 200 1000 1000
   vips extract_area sourceimage destinationimage 100 200 1000 1000
Show all header values, or specific values
   vips -a imagename
   vips -f width imagename
   vips -f height imagename
Save from tif to vips format and back again
   vips vipssave sourceimage.tif destinationimage.v
   vips tiffsave sourceimage.v destinationimage.tif
or
   vips copy sourceimage.tif destinationimage.v
Extract a region, copy it back to the same place
   vips extract_area sourceimage extractedimage 100 200 1000 1000
   ... do something to the extractedimage ...
   vips insert extractedimage destinationimage 100 200
To show progress and/or memory usage add the following to any vips command
   --vips-progress --vips-leak
Image statistics
   vips stats imagename .csv