turing.py 1.65 KB
Newer Older
wester committed
1 2 3 4 5 6 7 8 9 10 11
#!/usr/bin/env python

'''
Multiscale Turing Patterns generator
====================================

Inspired by http://www.jonathanmccabe.com/Cyclic_Symmetric_Multi-Scale_Turing_Patterns.pdf
'''

import numpy as np
import cv2
wester committed
12
import cv2.cv as cv
wester committed
13 14 15 16 17 18 19 20 21 22 23
from common import draw_str
import getopt, sys
from itertools import count

help_message = '''
USAGE: turing.py [-o <output.avi>]

Press ESC to stop.
'''

if __name__ == '__main__':
wester committed
24
    print help_message
wester committed
25 26 27 28 29 30 31 32

    w, h = 512, 512

    args, args_list = getopt.getopt(sys.argv[1:], 'o:', [])
    args = dict(args)
    out = None
    if '-o' in args:
        fn = args['-o']
wester committed
33 34
        out = cv2.VideoWriter(args['-o'], cv.CV_FOURCC(*'DIB '), 30.0, (w, h), False)
        print 'writing %s ...' % fn
wester committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

    a = np.zeros((h, w), np.float32)
    cv2.randu(a, np.array([0]), np.array([1]))

    def process_scale(a_lods, lod):
        d = a_lods[lod] - cv2.pyrUp(a_lods[lod+1])
        for i in xrange(lod):
            d = cv2.pyrUp(d)
        v = cv2.GaussianBlur(d*d, (3, 3), 0)
        return np.sign(d), v

    scale_num = 6
    for frame_i in count():
        a_lods = [a]
        for i in xrange(scale_num):
            a_lods.append(cv2.pyrDown(a_lods[-1]))
        ms, vs = [], []
        for i in xrange(1, scale_num):
            m, v = process_scale(a_lods, i)
            ms.append(m)
            vs.append(v)
        mi = np.argmin(vs, 0)
        a += np.choose(mi, ms) * 0.025
        a = (a-a.min()) / a.ptp()

        if out:
            out.write(a)
        vis = a.copy()
        draw_str(vis, (20, 20), 'frame %d' % frame_i)
        cv2.imshow('a', vis)
a  
Kai Westerkamp committed
65
        if 0xFF & cv2.waitKey(5) == 27:
wester committed
66 67
            break
    cv2.destroyAllWindows()