Color Thresholds and Masking with FFMpeg and ImageMagick

Color Thresholds and Masking with FFMpeg and ImageMagick

I’ve demonstrated how to take videos and convert them into images using FFMpeg in previous posts. In this post, I’ll be using that same process and ImageMagick to create a color threshold effect. The interesting aspect is that all of the processing can be done through the command line.

When faces with editing numerous files, scripting is the way to go. The few hours of up front work getting the script right is worth it. You can get on with your life and let the computer do the work, instead of spending days of mundane repetitive editing.

First, we need to convert our video to an image series, this command should do it.

ffmpeg -i "video.mov" -vf fps=30 "images%d.png"

Now I would suggest creating your file list text file, this will be referenced when you plan to take the image series in convert it back to video.

ls -t -r image*.png > filelist.txt

If you don’t create the reference file list text file, you’ll have sorting problems after using ImageMagick.

Next, I used these commands to convert the images with ImageMagick. They do four things, convert to gray-scale, hue-scale, saturation-scale, and brightness-scale.

for f in image*.png ; do convert "$f" -colorspace Gray converted_"$f"; done
for f in image*.png ; do convert "$f" -colorspace HSB -separate HSB%d_"$f"; done

Lets run another file list command, that way you can see what I mean about sorting hell.

ls -t -r converted*.png > filelist_hell.txt

The sort is messed up. Beleive me, I tried many methods and concluded that a base file list that had correct sorting was the easiest. I simply edit that file list with a simple substitution command.

sed 's/images/converted_images/' filelist.txt > converted_filelist.txt
sed 's/images/HSB0_images/' filelist.txt > HSB0_filelist.txt
sed 's/images/HSB1_images/' filelist.txt > HSB1_filelist.txt
sed 's/images/HSB2_images/' filelist.txt > HSB2_filelist.txt

Much easier than editing file lists manually to get the sequence correct for FFMpeg. Had you not, the resulting video would be wonky. Now let’s construct the videos from our intial bunch of processed image files.

ffmpeg -y -r 30 -f concat -safe 0 -i converted_filelist.txt -c:v libx264 -vf "fps=30" "Gray.mov"
ffmpeg -y -r 30 -f concat -safe 0 -i HSB0_filelist.txt -c:v libx264 -vf "fps=30" "Hue.mov"
ffmpeg -y -r 30 -f concat -safe 0 -i HSB1_filelist.txt -c:v libx264 -vf "fps=30" "Saturation.mov"
ffmpeg -y -r 30 -f concat -safe 0 -i HSB2_filelist.txt -c:v libx264 -vf "fps=30" "Brightness.mov"

These videos have some interesting aspects. However, I’m not impressed by the grayscale, it looks too dark. I prefer to edit the video directly by de-saturating the source and creating a more visually appealing grayscale video with this command.

ffmpeg -i "video.mov" -vf "eq=saturation=0" "De-Saturate.mov"

ImageMagick has been developed by numerious people over the years. Fred Weinhaus has created a large volume of ImageMagick scripts that makes life easier for the rest of us. I’ll be using isolatecolor (http://www.fmwconcepts.com/imagemagick/isolatecolor/index.php) script using this command.

for f in image*.png ; do ./isolatecolor -c 120 -t 18 -S 0 -s 100 "$f" mask_"$f"; done

As I’ve stated in previous posts, do your testing with sigle images before committing to a large quantity of image files. This process will take time depending on the number and file size of the images. My source was a 1080p video that spanned 10 seconds. It took 20 minutes to complete. Imagine if my video source was 8 hours, see were I’m going with this.

Now lets construct the video from this image series, but first we’ll need to construct our file list text file to get the correct sequence.

sed 's/images/mask_mages/' filelist.txt > mask_filelist.txt
ffmpeg -y -r 30 -f concat -safe 0 -i mask_filelist.txt -c:v libx264 -vf "fps=30" "Mask.mov"

This video is missing sound. When we converted our video to image sequences, we lost the sound. Let’s get the sound back on the audio track using these commands.

ffmpeg -i video.mov -acodec pcm_s16le -ac 2 video.wav
ffmpeg -i Mask.mov -i video.wav -codec copy -shortest Mask-Final.mov

The resulting video really gives an indication where the green grass grows, or where the dogs go, depending on the point of view. This is just a surface view of what ImageMagick can do. I hope you have enjoyed this post and I look forward to covering more FFMpeg topics in the future.

Comments are closed.