turing.py 1.64 KB
Newer Older
1
#!/usr/bin/env python
2

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
'''
Multiscale Turing Patterns generator
====================================

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

import numpy as np
import cv2
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__':
    print help_message

    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']
32
        out = cv2.VideoWriter(args['-o'], cv2.VideoWriter_fourcc(*'DIB '), 30.0, (w, h), False)
33 34 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 65 66
        print 'writing %s ...' % fn

    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)
        if 0xFF & cv2.waitKey(5) == 27:
            break
    cv2.destroyAllWindows()