Over the holidays, I had an idea about looping an animation between two images. I wrote some code to do this in Igor Pro (sorry, no R this time…). This post describes how the code works and how you can make a similar animation.
There was a reason to do this animation, but as a proof of principle I used two band logos. I picked Aerosmith and Run DMC since their collaborative re-recording of Aerosmith’s Walk This Way from their 1975 LP Toys in The Attic comes to my mind when I write a “walkthrough” document to describe my code.
Two images are needed for animation and it helps if they are a similar physical size. These images need to be loaded into Igor and binarized. This can be done using the image threshold tool. The binary images are fed into the code and they get turned into a series of PNGs that can be animated using ffmpeg or gifski (Igor can make movies but it is easier to do this using a command line tool that gives more flexibility).
So what happens under the hood?
The binarized images get converted to xy coordinates and the non-signal coords are disposed. The coord sets are centred relative to each other and then they get sampled. Not all coords are needed for a clear image and there is likely to be an unequal number of pixels between the two images, so Igor calculates the minimum number of coords between the two images and uses that multiplied by a “quality” factor. 1 for all pixels, 0.5 for half and so on.
Now we have an equal number of rows of xy coords between the two images. Next we need to make the transition states between the two images. This is done by randomising the XY position of each image. So we go from Image 1 – randomised set – image 2 – re-randomised set – back to image 1.
Next we build the animation. The code uses a simple interpolation method for each row to go from one state to the next. This could be made more complex, using a curve or other shape to animate the transition. This process builds a 3D matrix of XY coords with layers as frames of the animation. Next we display the coords of each layer in a graph window and save the output, replacing each layer and saving as we go.
The code has different options for colouring the output and controlling how many frames we use to transition between states.
At the end, we have a directory of PNGs that can be animated.
Using ffmpeg you can do something like:
ffmpeg -framerate 15 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p -vf scale=480:-2 output.mp4
To make the gif above, I first used ffmpeg, but then switched to gifski which makes really impressive animated gifs.
gifski -o walkthisway.gif *.png
This image was too big (physically). It is possible to reduce the physical size of the gif output like this:
gifski -W 869 -o walkthisway.gif *.png
The code is available here. Well, it runs OK and gives a result I’m happy with but what improvements could be made?
- The step of feeding in the images relies on manual input. and it would be nice if the user just feeds in the images and out pops the frames. Thresholding is hard. The logos I found on the web were in different formats (black on white, white-on-black, colour etc) and so this part is hard to automate. Especially since the Image thresholding in Igor is limited.
- There is plenty of room for extension (as described above) to make the animation more fancy
- Selecting colours and quality is currently hard-coded. If this were a bigger project the user could preselect these options at the start.
- On the positive side: the code is fast and it is probably possible to optimise it further, but right now it saves out each megapixel frame in a few hundred milliseconds.
The post title is taken from “Walk This Way” obviously…