From 4b60dcc05910a60933632a7f3b0f498c371a5fc1 Mon Sep 17 00:00:00 2001 From: Franc Date: Tue, 21 Mar 2017 20:16:28 +0100 Subject: [PATCH] first --- floppies/franc/.DS_Store | Bin 0 -> 6148 bytes floppies/franc/LICENSE | 1 + floppies/franc/README | 7 ++ floppies/franc/common.py | 217 ++++++++++++++++++++++++++++++++ floppies/franc/common.pyc | Bin 0 -> 12499 bytes floppies/franc/main.pd | 66 ++++++++++ floppies/franc/main.py | 156 +++++++++++++++++++++++ floppies/franc/noweb/index.html | 1 + floppies/franc/video.py | 194 ++++++++++++++++++++++++++++ floppies/franc/video.pyc | Bin 0 -> 8006 bytes 10 files changed, 642 insertions(+) create mode 100644 floppies/franc/.DS_Store create mode 100644 floppies/franc/LICENSE create mode 100644 floppies/franc/README create mode 100755 floppies/franc/common.py create mode 100644 floppies/franc/common.pyc create mode 100644 floppies/franc/main.pd create mode 100644 floppies/franc/main.py create mode 100644 floppies/franc/noweb/index.html create mode 100755 floppies/franc/video.py create mode 100644 floppies/franc/video.pyc diff --git a/floppies/franc/.DS_Store b/floppies/franc/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 0 and y1-y0 > 0: + self.drag_rect = (x0, y0, x1, y1) + else: + rect = self.drag_rect + self.drag_start = None + self.drag_rect = None + if rect: + self.callback(rect) + def draw(self, vis): + if not self.drag_rect: + return False + x0, y0, x1, y1 = self.drag_rect + cv2.rectangle(vis, (x0, y0), (x1, y1), (0, 255, 0), 2) + return True + @property + def dragging(self): + return self.drag_rect is not None + + +def grouper(n, iterable, fillvalue=None): + '''grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx''' + args = [iter(iterable)] * n + return it.izip_longest(fillvalue=fillvalue, *args) + +def mosaic(w, imgs): + '''Make a grid from images. + + w -- number of grid columns + imgs -- images (must have same size and format) + ''' + imgs = iter(imgs) + img0 = imgs.next() + pad = np.zeros_like(img0) + imgs = it.chain([img0], imgs) + rows = grouper(w, imgs, pad) + return np.vstack(map(np.hstack, rows)) + +def getsize(img): + h, w = img.shape[:2] + return w, h + +def mdot(*args): + return reduce(np.dot, args) + +def draw_keypoints(vis, keypoints, color = (0, 255, 255)): + for kp in keypoints: + x, y = kp.pt + cv2.circle(vis, (int(x), int(y)), 2, color) diff --git a/floppies/franc/common.pyc b/floppies/franc/common.pyc new file mode 100644 index 0000000000000000000000000000000000000000..809781fc752bcfe4e9386d088087ea324d4f92b5 GIT binary patch literal 12499 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 literal 0 HcmV?d00001 diff --git a/floppies/franc/main.pd b/floppies/franc/main.pd new file mode 100644 index 0000000..63b9ed9 --- /dev/null +++ b/floppies/franc/main.pd @@ -0,0 +1,66 @@ +#N canvas 136 23 897 545 10; +#X floatatom 166 153 5 0 0 0 - - -; +#X floatatom 282 159 5 0 0 0 - - -; +#X obj 54 -92 tgl 15 0 empty empty empty 17 7 0 10 -262130 -1 -1 1 +1; +#X msg 54 -54 \; pd dsp \$1; +#X obj 267 -7 OSC/unpackOSC; +#X obj 267 -46 iemnet/udpreceive 9001; +#X obj 267 33 OSC/routeOSC /dot; +#X obj 190 121 unpack f f; +#N canvas 0 22 450 278 (subpatch) 0; +#X array waveform 11 float 1; +#A 0 -1 -1 -1 -1 -1 -1 -1 -0.333333 0 0.333333 -1; +#X coords 0 1 10 -1 200 140 1 0 0; +#X restore 494 188 graph; +#X obj 224 247 tabwrite waveform; +#X obj 264 189 t b f; +#X obj 225 220 f; +#X obj 198 354 tabread4~ waveform; +#X obj 232 401 dac~; +#X obj 488 116 tabread waveform; +#X obj 543 23 + 1; +#X obj 505 21 i; +#X obj 504 -39 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 +1; +#X msg 534 78 0; +#X floatatom 483 72 5 0 0 0 - - -; +#X floatatom 424 254 5 0 0 0 - - -; +#X obj 535 54 select 10; +#X obj 204 325 *~ 10; +#X obj 416 207 + 1; +#X obj 506 -9 metro 100; +#X obj 196 295 osc~; +#X obj 364 370 line~; +#X msg 364 342 \$1 10; +#X obj 337 295 expr 100 + (100 * $f1); +#X connect 2 0 3 0; +#X connect 4 0 6 0; +#X connect 5 0 4 0; +#X connect 6 0 7 0; +#X connect 7 0 0 0; +#X connect 7 0 10 0; +#X connect 7 1 1 0; +#X connect 7 1 11 1; +#X connect 10 0 11 0; +#X connect 10 1 9 1; +#X connect 11 0 9 0; +#X connect 12 0 13 0; +#X connect 12 0 13 1; +#X connect 14 0 23 0; +#X connect 15 0 16 1; +#X connect 16 0 15 0; +#X connect 16 0 19 0; +#X connect 16 0 14 0; +#X connect 16 0 21 0; +#X connect 17 0 24 0; +#X connect 18 0 16 1; +#X connect 21 0 18 0; +#X connect 22 0 12 0; +#X connect 23 0 20 0; +#X connect 23 0 28 0; +#X connect 24 0 16 0; +#X connect 25 0 22 0; +#X connect 27 0 26 0; +#X connect 28 0 27 0; +#X connect 28 0 25 0; diff --git a/floppies/franc/main.py b/floppies/franc/main.py new file mode 100644 index 0000000..6f912c7 --- /dev/null +++ b/floppies/franc/main.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python + +import numpy as np +import cv2, math +import video + +help_message = ''' +USAGE: opt_flow.py [] + +Keys: + 1 - toggle HSV flow visualization + 2 - toggle glitch + +''' + +# def draw_flow(img, flow, step=4): # size grid +# h, w = img.shape[:2] +# y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1) +# fx, fy = flow[y,x].T +# lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2) +# lines = np.int32(lines + 0.5) +# vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) +# cv2.polylines(vis, lines, 0, (0, 0, 255)) # BGR +# for (x1, y1), (x2, y2) in lines: +# cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1) +# return vis + +import OSC +# from pythonosc import osc_message_builder +# from pythonosc import udp_client +import time + +def send_flow0(img, flow, step=4): # size grid + h, w = img.shape[:2] + y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1) + fx, fy = flow[y,x].T + #print "fx, fy", fx, fy + lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2) + lines = np.int32(lines + 0.5) + vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + + + flines = [] + for (x1, y1), (x2, y2) in lines: + # print ("y1", y1) + if (x1 == 38 or x1 == 46 or x1 == 54 or x1 == 62 or x1 == 70 or x1 == 78 or x1 == 86 or x1 == 94 or x1 == 102 or x1 == 110 or x1 == 118) and y1 in range(38, 90, 8): + flines.append(((x1,y1),(x2,y2))) + normx = x1 / 8 - 4 + normy = 1 - ((y1 / 8 - 4) / 3.0) + dx = x2-x1 + dy = y2 - y1 + m = int(math.sqrt( (dx*dx) + (dy*dy) )) + if m>2: + print ("dot", (normx, normy)) + msg = OSC.OSCMessage() + msg.setAddress("/dot") + #msg.append(dx) + #msg.append(dy) + #msg.append(m) + msg.append(normx) + msg.append(normy) + client.send(msg) + # client.send_message("/franc", m) + + + # for (x1, y1), (x2, y2) in lines: + # # print ("y1", y1) + # if (y1 == 38 or y1 == 46 or y1 == 54 or y1 == 70 or y1 == 86) and x1 in range(38, 118, 8): + # flines.append(((x1,y1),(x2,y2))) + # dx = x2-x1 + # dy = y2 - y1 + # m = int(math.sqrt( (dx*dx) + (dy*dy) )) + # if m>2: + # print ("x", (dx, dy, m, x1, y1)) + # msg = OSC.OSCMessage() + # msg.setAddress("/x") + # msg.append(dx) + # msg.append(dy) + # msg.append(m) + # msg.append(x1) + # msg.append(y1) + # client.send(msg) + + + # Here goes BPM + + + + + # for (x1, y1), (x2, y2) in lines: + # # print ("y1", y1) + # if (y1 == 10 or y1 == 110) and x1 in range(90, 150, 4): + # flines.append(((x1,y1),(x2,y2))) + # dx = x2-x1 + # dy = y2 - y1 + # m = int(math.sqrt( (dx*dx) + (dy*dy) )) + # if m>2: + # print ("l", (dx, dy, m, x1, y1)) + # msg = OSC.OSCMessage() + # msg.setAddress("/left") + # msg.append(dx) + # msg.append(dy) + # msg.append(m) + # msg.append(x1) + # msg.append(y1) + # client.send(msg) + + + flines = np.int32(flines) + cv2.polylines(vis, flines, 0, (0, 40, 255)) # BGR + for (x1, y1), (x2, y2) in flines: + cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1) + return vis + + flines = np.int32(flines) + cv2.polylines(vis, flines, 0, (0, 40, 255)) # BGR + for (x1, y1), (x2, y2) in flines: + cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1) + return vis + + # cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) + +if __name__ == '__main__': + import sys + print help_message + try: fn = sys.argv[1] + except: fn = 0 + + + # connect to pd + # Init OSC + client = OSC.OSCClient() + client.connect(('127.0.0.1', 9001)) # first argument is the IP of the host, second argument is the port to use + #data="hello" + # client = udp_client.SimpleUDPClient("127.0.0.1", 9001) + + # connect camera + # cam = video.create_capture(fn) + cam = video.create_capture("0:size=160x120") #canvas size in pixels + ret, prev = cam.read() + prevgray = cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY) + cur_glitch = prev.copy() + + while True: + # print "GRAB FRAME" + ret, img = cam.read() + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + flow = cv2.calcOpticalFlowFarneback(prevgray, gray, 0.5, 3, 15, 3, 5, 1.2, 0) + prevgray = gray + + cv2.imshow('flow', send_flow0(gray, flow)) + + ch = 0xFF & cv2.waitKey(5) + if ch == 27: + break + cv2.destroyAllWindows() diff --git a/floppies/franc/noweb/index.html b/floppies/franc/noweb/index.html new file mode 100644 index 0000000..bc6fe43 --- /dev/null +++ b/floppies/franc/noweb/index.html @@ -0,0 +1 @@ +GREAT JOB! diff --git a/floppies/franc/video.py b/floppies/franc/video.py new file mode 100755 index 0000000..7e90ded --- /dev/null +++ b/floppies/franc/video.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python + +''' +Video capture sample. + +Sample shows how VideoCapture class can be used to acquire video +frames from a camera of a movie file. Also the sample provides +an example of procedural video generation by an object, mimicking +the VideoCapture interface (see Chess class). + +'create_capture' is a convinience function for capture creation, +falling back to procedural video in case of error. + +Usage: + video.py [--shotdir ] [source0] [source1] ...' + + sourceN is an + - integer number for camera capture + - name of video file + - synth: for procedural video + +Synth examples: + synth:bg=../cpp/lena.jpg:noise=0.1 + synth:class=chess:bg=../cpp/lena.jpg:noise=0.1:size=640x480 + +Keys: + ESC - exit + SPACE - save current frame to directory + +''' + +import numpy as np +import cv2 +from time import clock +from numpy import pi, sin, cos +import common + +class VideoSynthBase(object): + def __init__(self, size=None, noise=0.0, bg = None, **params): + self.bg = None + self.frame_size = (640, 480) + if bg is not None: + self.bg = cv2.imread(bg, 1) + h, w = self.bg.shape[:2] + self.frame_size = (w, h) + + if size is not None: + w, h = map(int, size.split('x')) + self.frame_size = (w, h) + self.bg = cv2.resize(self.bg, self.frame_size) + + self.noise = float(noise) + + def render(self, dst): + pass + + def read(self, dst=None): + w, h = self.frame_size + + if self.bg is None: + buf = np.zeros((h, w, 3), np.uint8) + else: + buf = self.bg.copy() + + self.render(buf) + + if self.noise > 0.0: + noise = np.zeros((h, w, 3), np.int8) + cv2.randn(noise, np.zeros(3), np.ones(3)*255*self.noise) + buf = cv2.add(buf, noise, dtype=cv2.CV_8UC3) + return True, buf + + def isOpened(self): + return True + +class Chess(VideoSynthBase): + def __init__(self, **kw): + super(Chess, self).__init__(**kw) + + w, h = self.frame_size + + self.grid_size = sx, sy = 10, 7 + white_quads = [] + black_quads = [] + for i, j in np.ndindex(sy, sx): + q = [[j, i, 0], [j+1, i, 0], [j+1, i+1, 0], [j, i+1, 0]] + [white_quads, black_quads][(i + j) % 2].append(q) + self.white_quads = np.float32(white_quads) + self.black_quads = np.float32(black_quads) + + fx = 0.9 + self.K = np.float64([[fx*w, 0, 0.5*(w-1)], + [0, fx*w, 0.5*(h-1)], + [0.0,0.0, 1.0]]) + + self.dist_coef = np.float64([-0.2, 0.1, 0, 0]) + self.t = 0 + + def draw_quads(self, img, quads, color = (0, 255, 0)): + img_quads = cv2.projectPoints(quads.reshape(-1, 3), self.rvec, self.tvec, self.K, self.dist_coef) [0] + img_quads.shape = quads.shape[:2] + (2,) + for q in img_quads: + cv2.fillConvexPoly(img, np.int32(q*4), color, cv2.CV_AA, shift=2) + + def render(self, dst): + t = self.t + self.t += 1.0/30.0 + + sx, sy = self.grid_size + center = np.array([0.5*sx, 0.5*sy, 0.0]) + phi = pi/3 + sin(t*3)*pi/8 + c, s = cos(phi), sin(phi) + ofs = np.array([sin(1.2*t), cos(1.8*t), 0]) * sx * 0.2 + eye_pos = center + np.array([cos(t)*c, sin(t)*c, s]) * 15.0 + ofs + target_pos = center + ofs + + R, self.tvec = common.lookat(eye_pos, target_pos) + self.rvec = common.mtx2rvec(R) + + self.draw_quads(dst, self.white_quads, (245, 245, 245)) + self.draw_quads(dst, self.black_quads, (10, 10, 10)) + + +classes = dict(chess=Chess) + +presets = dict( + empty = 'synth:', + lena = 'synth:bg=../cpp/lena.jpg:noise=0.1', + chess = 'synth:class=chess:bg=../cpp/lena.jpg:noise=0.1:size=640x480' +) + + +def create_capture(source = 0, fallback = presets['chess']): + '''source: or '||synth [:= [:...]]' + ''' + source = str(source).strip() + chunks = source.split(':') + # hanlde drive letter ('c:', ...) + if len(chunks) > 1 and len(chunks[0]) == 1 and chunks[0].isalpha(): + chunks[1] = chunks[0] + ':' + chunks[1] + del chunks[0] + + source = chunks[0] + try: source = int(source) + except ValueError: pass + params = dict( s.split('=') for s in chunks[1:] ) + + cap = None + if source == 'synth': + Class = classes.get(params.get('class', None), VideoSynthBase) + try: cap = Class(**params) + except: pass + else: + cap = cv2.VideoCapture(source) + if 'size' in params: + w, h = map(int, params['size'].split('x')) + cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, w) + cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, h) + if cap is None or not cap.isOpened(): + print 'Warning: unable to open video source: ', source + if fallback is not None: + return create_capture(fallback, None) + return cap + +if __name__ == '__main__': + import sys + import getopt + + print __doc__ + + args, sources = getopt.getopt(sys.argv[1:], '', 'shotdir=') + args = dict(args) + shotdir = args.get('--shotdir', '.') + if len(sources) == 0: + sources = [ 0 ] + + caps = map(create_capture, sources) + shot_idx = 0 + while True: + imgs = [] + for i, cap in enumerate(caps): + ret, img = cap.read() + imgs.append(img) + cv2.imshow('capture %d' % i, img) + ch = 0xFF & cv2.waitKey(1) + if ch == 27: + break + if ch == ord(' '): + for i, img in enumerate(imgs): + fn = '%s/shot_%d_%03d.bmp' % (shotdir, i, shot_idx) + cv2.imwrite(fn, img) + print fn, 'saved' + shot_idx += 1 + cv2.destroyAllWindows() diff --git a/floppies/franc/video.pyc b/floppies/franc/video.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24e2adb9bcd2f98c9915a5882306d9a32241e116 GIT binary patch literal 8006 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 literal 0 HcmV?d00001