Friday 11 June 2021

Black and white ( The future is 1 bit)


  A while back I became interested in dithering - an early technique used for creating grey scale images in the days when computer monitors, and sometimes computers, were only black and white - think early Macintosh or that portable black and white TV you used for your ZX81 or any of the early home computers. Very similar to newspapers grid of dots dithering has a certain aesthetic appeal - there's a wonderful article here on its roots and links to modern processing sketches https://www.evilmadscientist.com/2012/dithering/ but that doesn't fill my requirements these are great but what if I want to turn a whole video into black and white ( not greyscale) rather than just capture it live . Something like this :

 


There's a simple way to do this in ffmpeg using this command - 'ffmpeg -i Input_1280x720.mp4 -f lavfi -i color=gray:s=1280x720 -f lavfi -i color=black:s=1280x720 -f lavfi -i color=white:s=1280x720 -filter_complex threshold output.mp4' - which gives us this:


Although I like this - its not quite what I was looking for . So I looked for some alternative way using ffmpeg to create dither but none of the methods I found gave me that look and feel . Then I thought well could I just convert the video to stills and use an old format like pbm and researching this I found that the netpbm library ( find netpbm page and links here ) has a function for creating atkinson like dither.

 Most linux distros come with the netpbm library and that gives us  different ways of dithering an image but the one I was most interested in - pamditherbw ( which has the setting for Atkinson dithering) didn't seem to be included which sent me down a rabbit hole of finding out why . To get this function you have to uninstall the netpbm that comes with your distro then download the deb file from here and carefully follow error messages that the installing with gdebi process throws up ( there are a couple of packages that need to be uninstalled and another that needs to be installed as well as the netpbm package ) - I know this sounds a little vaguer than I usually write but its easy enough when you see the process and follow the prompts. 

So having that installed I could now run the script I wanted to run which gives me this, best viewed full screen ( I'll post the script at the end )


This is the script : caveats - you must remember to add file extension when answering 'what do you want to name the output file' ie mp4 - if using a different codec other than h264 you may wish to alter the ffmpeg statement at the end . It creates a lot of files when its working , so you might want to use a scratch disk ( I did a fifty minute video which created 80000 plus files here but it does clean up after itself ie removes the stills before exiting.

#!/bin/bash
#to get pam ditherbw to work uninstall pkgmanagers version of netpbm and download and from here https://sourceforge.net/projects/netpbm/files/
#more info on pamditherbw here http://netpbm.sourceforge.net/doc/pamditherbw.html

echo -n "File to work on ? : "
read n

echo -n "What do you want to name output file ? : "
read z

echo -n "Framerate as a number between 1 and 30 ? : "
read m

echo -n "crf value for final video ? : "
read o




# convert to pgm

ffmpeg -i $n -vf fps=$m image-%05d.pgm

i=0
find . -type f -name '*.pgm'|while read filename; do echo ${filename} ;
((i++))
# try different random seeds
  pamditherbw -atkinson -randomseed 8  ${filename} > $i.pam ;
  mogrify -format pbm $i.pam
  mv "$i.pbm" "$(basename "${filename}" .pgm).pbm"
  rm $i.pam
 
  done
 
 
 
  rm *.pam
  rm *.pgm
 




ffmpeg -i image-%05d.pbm -vcodec libx264 -r $m -crf $o  -pix_fmt yuv420p $z
#ffmpeg -i image-%05d.pbm -r $m -c:v hevc -b:v 2M  $z

rm *.pbm


#ffmpeg -r $m -i %d.jpg -i $n -map 0:0 -map 1:1 -c:a copy -c:v libx264 -tune stillimage -crf $o -r 24 lol.mp4





ikillerpulse ( requires tomato.py in working directory)

I've been working on this script for the last week or so. What does it do? It takes an input video/s,  converts to a format we can use f...