1#!/usr/bin/env python 2 3''' 4Multiscale Turing Patterns generator 5==================================== 6 7Inspired by http://www.jonathanmccabe.com/Cyclic_Symmetric_Multi-Scale_Turing_Patterns.pdf 8''' 9 10import numpy as np 11import cv2 12from common import draw_str 13import getopt, sys 14from itertools import count 15 16help_message = ''' 17USAGE: turing.py [-o <output.avi>] 18 19Press ESC to stop. 20''' 21 22if __name__ == '__main__': 23 print help_message 24 25 w, h = 512, 512 26 27 args, args_list = getopt.getopt(sys.argv[1:], 'o:', []) 28 args = dict(args) 29 out = None 30 if '-o' in args: 31 fn = args['-o'] 32 out = cv2.VideoWriter(args['-o'], cv2.VideoWriter_fourcc(*'DIB '), 30.0, (w, h), False) 33 print 'writing %s ...' % fn 34 35 a = np.zeros((h, w), np.float32) 36 cv2.randu(a, np.array([0]), np.array([1])) 37 38 def process_scale(a_lods, lod): 39 d = a_lods[lod] - cv2.pyrUp(a_lods[lod+1]) 40 for i in xrange(lod): 41 d = cv2.pyrUp(d) 42 v = cv2.GaussianBlur(d*d, (3, 3), 0) 43 return np.sign(d), v 44 45 scale_num = 6 46 for frame_i in count(): 47 a_lods = [a] 48 for i in xrange(scale_num): 49 a_lods.append(cv2.pyrDown(a_lods[-1])) 50 ms, vs = [], [] 51 for i in xrange(1, scale_num): 52 m, v = process_scale(a_lods, i) 53 ms.append(m) 54 vs.append(v) 55 mi = np.argmin(vs, 0) 56 a += np.choose(mi, ms) * 0.025 57 a = (a-a.min()) / a.ptp() 58 59 if out: 60 out.write(a) 61 vis = a.copy() 62 draw_str(vis, (20, 20), 'frame %d' % frame_i) 63 cv2.imshow('a', vis) 64 if 0xFF & cv2.waitKey(5) == 27: 65 break 66 cv2.destroyAllWindows() 67