Wednesday, April 30, 2008

Scripting JPGs to WMV to create Time Lapse videos

At my primary job I am responsible for 5 construction cameras that monitor a major downtown redevelopment project. These cameras provide video as well as take period snapshots, both of which can be accessed remotely via a web interface. The cameras are 4 Axis 232D+, and one Axis 233D. There's a ton I could write about this whole project, but I mainly wanted to document my current procedure for taking the JPG images and converting them to video files to be used in powerpoint, put on DVD, etc. I'm writing this for my own benefit and documentation, so things may be sketchy, feel free to ask me if you have any questions. This is a work in process...

These are PTZ cameras, and they are each programmed with 3-6 preset positions at which they take a still image, every half an hour from 8am to 6pm. That means that every half an hour I get still shots of about 20 different views. All of these views can be used to create time lapse videos. The powers that be would like a time lapse video of every sequence (or view) once per quarter. I use Adobe Premiere all the time, but it would be insane to try to accomplish this with that product - enter open source.

Ok, here is the basic workflow:

  1. Use windows find to get just the images I want. I'm using vista, so I can use advanced query syntax. The cameras take images every half an hour - for longer spanning time lapses I typically just want one picture per day. Because I want a certain time each day, I can't use date/time criteria for search, so I use the file name, which are all datetime stamped. Syntax for one per day:
    name:*16-0?-??-??.jpg

    syntax for range:
    name:*12-0?-??-??.jpg OR name:*13-0?-??-??.jpg OR name:*14-0?-??-??.jpg OR name:*15-0?-??-??.jpg OR name:*16-0?-??-??.jpg OR name:*17-0?-??-??.jpg OR name:*18-0?-??-??.jpg OR name:*19-0?-??-??.jpg OR

    The latter would give me all images at 12pm, 1,2,3,4,5,6,and 7pm. By the way, I use a vbs script to sort all the images the camera takes into folders for each camera, sequence, year, and quarter. Maybe I'll write about that part of it later.

  2. Once I've found the images I want, I process them with a utility called MakeAVI (http://sourceforge.net/projects/makeavi/). Two things I'd like to see in this program: drag and drop and command line scripting. I found some paid versions out there that do this, but I like free, and for the most part this program does the simple job it's programmed to do (a user on sourceforge actually took the source code and made it scriptable through a CLI, but neither the source or the binary for that is posted - I emailed to see if it was available). Because I can't drag from my search window into MakeAVI, I copy the files to an empty folder and then add the files from there. When using MakeAVI, I use the DivX encoder to compress the AVI files. Uncompressed takes longer and the file size is unnecessarily huge. I don't want to lose much quality, so my DivX settings are: Certification Profile: Home Theater Profile; Use presets to configure the encoder: checked; Rate control mode: 1 pass quality based; Target quantizer: 1; no other changes.

  3. Convert the DivX avi to a WMV file. Personally, I'd be happy with DivX, but these will be used in PowerPoint, so WMV is your best bet for compatability there. For this I use a slick little program called SUPER. It's basically a gui to a ton of different codecs and open source utilities. You can batch process, so I typically create all of my avi's first, then batch process them all to WMV. My settings in SUPER are: Output Container: WMV; Output Video Codec: WMV8; audio is disabled; Video Scale size: no change; aspect: no selection; Frame/Sec: 25; Bitrate: 4032 (quite high, I know, but I've found it needs to be at least this high to avoid blocky compression artifacts);Options: High Quality. SUPER is scriptable, so I may create a script to automatically process all my AVIs for me, but it's pretty easy to just add them manually and batch process them.


Other notes:
Because the files are all on a server on my network, it would be a pain to copy all the files locally that I needed. So I use offline files in Vista. Vista handles caching all the files locally, then when I want to process them I tell Vista to work offline. The when processing the images it uses the local copies.

I'm working on a script to automatically copy the appropriate images I need into various folders, all ready to be processed with MakeAVI, rather than having to do a windows search, and copy routine, like in step #1.