[OBSOLETE] Raw deflickering for timelapse

Started by a1ex, September 04, 2012, 09:33:54 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

a1ex

This script is obsolete; I've implemented the same algorithm directly in the camera (Post Deflicker).

If you are interested in the internals of this algorithm, you are welcome to take a look.

Bulb ramping is not 100% flicker-free and it will never be, since it measures the exposure from previous shots and it won't account for natural flicker. At fast shutter speeds, the flicker comes from the discrete shutter speeds enforced by Canon firmware.

So, I'm trying to get a script which should do perfect deflicker, based on robust statistics (median) and RAW image data. It should work even if you simply shoot in Auto or Manual, without any ramping.

Version 0.2 - tested on 800 pictures (video below) and added a real-time deflicker graph.
Version 0.1 - only tested on 10 pictures, with very promising results.




You need Python 2.x, numpy/scipy/matplotlib, dcraw, ufraw, imagemagick... and hopefully that's all.

Usage: create a folder named "raw" and another one named "jpg", paste your CR2 files under "raw" and run the script.

# RAW deflickering script
# Copyright (2012) a1ex. License: GPL.

from __future__ import division
import os, sys, re, time, datetime, subprocess, shlex
from math import *
from pylab import *

def progress(x, interval=1):
    global _progress_first_time, _progress_last_time, _progress_message, _progress_interval
   
    try:
        p = float(x)
        init = False
    except:
        init = True
       
    if init:
        _progress_message = x
        _progress_last_time = time.time()
        _progress_first_time = time.time()
        _progress_interval = interval
    elif x:
        if time.time() - _progress_last_time > _progress_interval:
            print >> sys.stderr, "%s [%d%% done, ETA %s]..." % (_progress_message, int(100*p), datetime.timedelta(seconds = round((1-p)/p*(time.time()-_progress_first_time))))
            _progress_last_time = time.time()


def change_ext(file, newext):
    if newext and (not newext.startswith(".")):
        newext = "." + newext
    return os.path.splitext(file)[0] + newext

def get_median(file):
    cmd1 = "dcraw -c -D -4 -o 0 '%s'" % file
    cmd2 = "convert - -type Grayscale -scale 500x500 -format %c histogram:info:-"
    #~ print cmd1, "|", cmd2
    p1 = subprocess.Popen(shlex.split(cmd1), stdout=subprocess.PIPE)
    p2 = subprocess.Popen(shlex.split(cmd2), stdin=p1.stdout, stdout=subprocess.PIPE)
    lines = p2.communicate()[0].split("\n")
    X = []
    for l in lines[1:]:
        p1 = l.find("(")
        if p1 > 0:
            p2 = l.find(",", p1)
            level = int(l[p1+1:p2])
            count = int(l[:p1-2])
            X += [level]*count
    m = median(X)
    return m

ion()

progress("Analyzing RAW exposures...");
files = sorted(os.listdir("raw"))
i = 0;
M = [];
for k,f in enumerate(files):
    m = get_median(os.path.join('raw', f))
    M.append(m);

    E = [-log2(m/M[0]) for m in M]
    E = detrend(array(E))
    cla(); stem(range(1,len(E)+1), E);
    xlabel('Image number')
    ylabel('Exposure correction (EV)')
    title(f)
    draw();
    progress(k / len(files))

progress("Developing JPG images...");
i = 0;
for k,f in enumerate(files):
    ec = 2 + E[k];
    cmd = "ufraw-batch --out-type=jpg --overwrite --clip=film --saturation=2 --exposure=%s '%s' --output='jpg/%s'" % (ec, os.path.join("raw", f), change_ext(f, ".jpg"))
    os.system(cmd)
    progress(k / len(files))
[/size]

a1ex

If you have some RAW footage with lots of flicker, please let me know, I'd like to test the script on some more demanding scenarios.

3pointedit

How big are the RAW files you generate, how big a card did you have for this moonrise? Seems like overkill for timelapse, but better for deflicker I guess.
550D on ML-roids

a1ex

For this example, the 850 sRAW shots have 10 GB.

There are no extra files generated by this workflow, only the final JPEGs developed from CR2's. The JPEGs took 135 MB.

rramirez125

I have some raw footage with flicker Alex, let me know how do we do it

scrax

Quote from: a1ex on September 05, 2012, 08:58:03 AM
If you have some RAW footage with lots of flicker, please let me know, I'd like to test the script on some more demanding scenarios.
I'll test it on something I have did with LRTimelapse, it's a timelapse done during the day only so no bulb ramping.
I'm using ML2.3 for photography with:
EOS 600DML | EOS 400Dplus | EOS 5D MLbeta5- EF 100mm f/2.8 USM Macro  - EF-S 17-85mm f4-5.6 IS USM - EF 70-200mm f/4 L USM - 580EXII - OsX, PS, LR, RawTherapee, LightZone -no video experience-

screamer

always trying to use the 100% of magic lantern..
Gear:
Canon 60D, all the samyang lenses, Canon 50 mm 1.4, Canon 60mm macro, Canon 70-300 usm, Sigma 4.5mm fisheye, Sigma 17-70 2.8, Canon 40mm f2.8 pancake, all the Lensbabies and a lot of other pieces, Flash metz 58 af2

Nick

EDIT: use the latest ufraw from CVS if your raws are coming from a 5dmk3.

a1ex

Yes, I've used the CVS UFRAW.

You have probably set a ramping speed factor too small.

Nick

Quote from: a1ex on September 07, 2012, 02:04:25 PM
Yes, I've used the CVS UFRAW.

You have probably set a ramping speed factor too small.

Compiling the CVS version now, should have a new lapse tomorrow.

0.050 EV for 15 seconds.. same as you suggested to me (if you meant max RampSpeed?).

a1ex

Here's the graph:



When the jump occured, ML was ramping at 0.11 EV / picture. When it has to ramp at twice the speed selected in menu, it jumps and no longer cares about smooth transition.

a1ex

New deflicker test, with some older footage:



I also wrote a small Windows GUI for this: if you'd like to try it, contact me. It should work on Mac too, in Wine.


dan.g

Would it be possible to output to .xmp instead?
I do stupid stuff when I'm drunk. Also, I write stupid signatures.

a1ex

If I understand well, that's some sort of EXIF info, no?

All the script does is to compute an exposure compensation for each RAW picture, so it shouldn't be hard. Do you have any links?

Malcolm Debono

I'd love to try it out as it sounds uber cool! Just need to find some (read: plenty of) time and go grab a timelapse  :D

Did you use bulb ramping (in-camera) when capturing the latest timelapse?
Wedding & event cinematographer
C100 & 6D shooter
New here?  Check out the FAQs here!

a1ex

The latest example was shot with an older version of bulb ramping.

This was from the same RAW shots: http://vimeo.com/44261518

MSU deflicker could not handle it, so I had to use heavy frame merging.

dan.g

Quote from: a1ex on September 09, 2012, 03:48:08 PM
If I understand well, that's some sort of EXIF info, no?

All the script does is to compute an exposure compensation for each RAW picture, so it shouldn't be hard. Do you have any links?

Not really an EXIF info, rather a sidecar file associated with the original RAW. If you can manage just to write the exposure compensation into the .xmp, we can continue processing the RAW files in Lightroom / Aperture or whatever program without going through the rather hard process of manual or semi-automatic deflickering. But after your script is done, we can still continue the RAW processing workflow.

Right now, your script is outputting to JPEG and doing so at the beginning of the workflow the postprocessing is done on a rather compressed format.

Wikipedia - XMP file example
I do stupid stuff when I'm drunk. Also, I write stupid signatures.

a1ex

Looks like exiftool can also set xmp tags, so probably it can be embedded in raw files:


exiftool -xmp:ExposureCompensation=2 IMG_1234.CR2


Can you confirm that your software recognizes exposure compensation set in this way? If yes, it's easy to modify the script and set the tags rather than developing jpegs.

dan.g

YES! Lightroom can definitely read metadata attached to a sidecar .xmp. Don't know for Aperture, but my guess it that it can read attached .xmp's as long as the filename is the same.
I do stupid stuff when I'm drunk. Also, I write stupid signatures.

a1ex

Great. Then, I think you can replace the last loop with this:


progress("Updating XMP tags...");
i = 0;
for k,f in enumerate(files):
    ec = E[k];
    cmd = "exiftool -xmp:ExposureCompensation=%f '%s'" % (ec, os.path.join("raw", f))
    os.system(cmd)
    progress(k / len(files))


or, for separate xmp files:


progress("Creating sidecar XMP files...");
i = 0;
for k,f in enumerate(files):
    ec = E[k];
    cmd = "exiftool -creator=me -xmp:ExposureCompensation=%f '%s'" % (ec, os.path.join("raw", change_ext(f, '.xmp'))
    os.system(cmd)
    progress(k / len(files))


Let me know if it works for you. I don't use Aperture nor Lightroom (just ufraw and some scripts).

dan.g

Thanks a lot, Alex!

It will take some time, haven't written a single line of code in 15 years, probably it will take me a few days to be able to run a script in python! :)

I'll keep you posted if it works, once I get the grip of it :)
I do stupid stuff when I'm drunk. Also, I write stupid signatures.

Malcolm Debono

+1 for metadata usage. In Lightroom, it's also super-easy to re-read the metadata for imported images (right click images and select Load metadata from file), and it works great with Lightroom's specific-setting syncing between multiple photos!
Wedding & event cinematographer
C100 & 6D shooter
New here?  Check out the FAQs here!

scrax

Quote from: dan.g on September 09, 2012, 07:09:26 PM
YES! Lightroom can definitely read metadata attached to a sidecar .xmp. Don't know for Aperture, but my guess it that it can read attached .xmp's as long as the filename is the same.
theuy also read exif data so why have another file?
I'm using ML2.3 for photography with:
EOS 600DML | EOS 400Dplus | EOS 5D MLbeta5- EF 100mm f/2.8 USM Macro  - EF-S 17-85mm f4-5.6 IS USM - EF 70-200mm f/4 L USM - 580EXII - OsX, PS, LR, RawTherapee, LightZone -no video experience-

dan.g

True. But Lightroom doesn't write exposure, white balance, etc. in EXIF in RAW files, afaik. I maybe wrong, though. So, this pushed me and lots of others to use sidecars where data can be both read and written. So, old habits die hard now :)
I do stupid stuff when I'm drunk. Also, I write stupid signatures.

Nick

The script works brilliantly.

Deflickered:


Original:


I'll try the .xmp mod next and see if I can post-process further in Lightroom and still export with no flicker. :)

Thanks for all your hard work Alex!