[pypy-commit] extradoc extradoc: dynamic video analytics develoopment demo, stage 1

hakanardo noreply at buildbot.pypy.org
Wed Sep 12 07:54:02 CEST 2012


Author: Hakan Ardo <hakan at debian.org>
Branch: extradoc
Changeset: r4787:1d4d53f768ee
Date: 2012-09-11 19:56 +0200
http://bitbucket.org/pypy/extradoc/changeset/1d4d53f768ee/

Log:	dynamic video analytics develoopment demo, stage 1

diff --git a/talk/dls2012/demo/image.py b/talk/dls2012/demo/image.py
new file mode 100644
--- /dev/null
+++ b/talk/dls2012/demo/image.py
@@ -0,0 +1,95 @@
+from array import array
+
+def binop(op):
+    def f(a, b):
+        if not isinstance(a, Image):
+            a = ConstantImage(b.width, b.height, a)
+        if not isinstance(b, Image):
+            b = ConstantImage(a.width, a.height, b)
+
+        out = a.new(typecode='d')
+        for y in xrange(a.height):
+            for x in xrange(a.width):
+                out[x, y] = op(float(a[x, y]), float(b[x, y]))
+
+        return out
+    return f
+
+class Image(object):
+    def __init__(self, w, h, typecode='d', data=None):
+        self.width = w
+        self.height = h
+        if data is None:
+            self.data = array(typecode, [0]) * (w*h)
+        else:
+            self.data = data
+
+    def new(self, w=None, h=None, typecode=None):
+        if w is None:
+            w = self.width
+        if h is None:
+            h = self.height
+        if typecode is None:
+            typecode = self.typecode
+        return Image(w, h, typecode)
+
+    def __getitem__(self, (x, y)):
+        if 0 <= x < self.width and 0 <= y < self.height:
+            return self.data[y * self.width + x]
+        return 0
+
+    def __setitem__(self, (x, y), value):
+        if 0 <= x < self.width and 0 <= y < self.height:
+            self.data[y * self.width + x] = value
+
+    __add__ = binop(float.__add__)
+    __sub__ = binop(float.__sub__)
+    __mul__ = binop(float.__mul__)
+    __div__ = binop(float.__div__)
+
+    __radd__ = binop(float.__radd__)
+    __rsub__ = binop(float.__rsub__)
+    __rmul__ = binop(float.__rmul__)
+    __rdiv__ = binop(float.__rdiv__)
+
+    __lt__ = binop(float.__lt__)
+    __le__ = binop(float.__le__)
+    __eq__ = binop(float.__eq__)
+    __ne__ = binop(float.__ne__)
+    __gt__ = binop(float.__gt__)
+    __ge__ = binop(float.__ge__)
+
+    def __nonzero__(self):
+        return all(self.data)
+
+class ConstantImage(Image):
+    def __init__(self, w, h, value):
+        self.width = w
+        self.height = h
+        self.value = value
+
+    def __getitem__(self, (x, y)):
+        return self.value
+
+    def __setitem__(self, (x, y), value):
+        raise TypeError('ConstantImage does not support item assignment')
+
+
+def test_image():
+    img = Image(10, 20)
+    img[3, 4] = 7
+    assert img[3, 4] == 7
+    img[1, 2] = 42
+    assert img[1, 2] == 42
+
+    img2 = img + img
+    assert img2[1, 2] == 84
+    assert img2[3, 4] == 14
+
+    img += 1
+    assert img[2, 1] == 1
+    assert img[3, 4] == 8
+    assert img + img == 2 * img == img * 2
+    assert not (2 * img == 3 * img)
+    
+
diff --git a/talk/dls2012/demo/io.py b/talk/dls2012/demo/io.py
new file mode 100644
--- /dev/null
+++ b/talk/dls2012/demo/io.py
@@ -0,0 +1,68 @@
+from subprocess import Popen, PIPE, STDOUT
+import os, re
+from image import Image
+from array import array
+
+def mplayer(filename='tv://', options=()):
+    cmd = Popen(['mplayer', '-vo', 'null', '-ao', 'null',
+                 '-frames', '1'] + list(options) + [filename],
+                stdin=PIPE, stdout=PIPE, stderr=PIPE)
+    (out, err) = cmd.communicate()
+    for line in (out + err).split('\n'):
+        m = re.search('(VIDEO|VO): .*? (\d+)x(\d+)', line)
+        if m:
+            width, height = int(m.group(2)), int(m.group(3))
+            break
+    else:
+        raise IOError
+    fmt = 'y8'
+
+    mplayer = Popen(['mencoder', '-o', '-',
+                                 '-ovc', 'raw', '-of', 'rawvideo',
+                                 '-vf', 'format=' + fmt,
+                                 '-nosound', '-really-quiet',
+                    ] + list(options) + [filename],
+                    stdin=PIPE, stdout=PIPE, stderr=PIPE)
+    while True:
+        try:
+            data = array('B')
+            data.fromfile(mplayer.stdout, width*height)
+            img = Image(width, height, 'B', data)
+        except EOFError:
+            raise StopIteration
+        yield img
+
+        
+
+class MplayerViewer(object):
+    def __init__(self):
+        self.width = self.height = None
+    def view(self, img):
+        if img.data.typecode != 'B':
+            out = img.new(typecode='B')
+            for y in xrange(img.height):
+                for x in xrange(img.width):
+                    out[x, y] = int(min(max(img[x, y], 0), 255))
+            img = out
+        if not self.width:
+            w, h = img.width, img.height
+            self.mplayer = Popen(['mplayer', '-', '-benchmark',
+                                  '-demuxer', 'rawvideo',
+                                 '-rawvideo', 'w=%d:h=%d:format=y8' % (w, h),
+                                 '-really-quiet'],
+                                 stdin=PIPE, stdout=PIPE, stderr=PIPE)
+            
+            self.width = img.width
+            self.height = img.height
+        assert self.width == img.width
+        assert self.height == img.height
+        img.data.tofile(self.mplayer.stdin)
+
+viewers = {}
+def view(img, name='default'):
+    try:
+        viewer = viewers[name]
+    except KeyError:
+        viewer = viewers[name] = MplayerViewer()
+    viewer.view(img)
+    
diff --git a/talk/dls2012/demo/process.py b/talk/dls2012/demo/process.py
new file mode 100644
--- /dev/null
+++ b/talk/dls2012/demo/process.py
@@ -0,0 +1,8 @@
+from reloader import ReloadHack
+
+ at ReloadHack
+def process(video):
+    for img in video:
+        yield img  
+
+
diff --git a/talk/dls2012/demo/reloader.py b/talk/dls2012/demo/reloader.py
new file mode 100644
--- /dev/null
+++ b/talk/dls2012/demo/reloader.py
@@ -0,0 +1,36 @@
+import os, sys, time, traceback
+
+class ReloadHack(object):
+    def __init__(self, iterator_class):
+        self.module = sys.modules[iterator_class.__module__]
+        self.filename = self.module.__file__
+        if self.filename.endswith('.pyc'):
+            self.filename = self.filename[:-1]
+        self.name = iterator_class.__name__
+        self.mtime = -1
+        self.iterator_class = iterator_class
+
+    def __call__(self, *args, **kwargs):
+        def wrapper():
+            while True:
+                while True:
+                    try:
+                        mtime = os.stat(self.filename).st_mtime
+                    except OSError:
+                        pass
+                    else:
+                        try:
+                            if mtime > self.mtime:
+                                self.mtime = mtime
+                                reload(self.module)
+                                self.iterator_class = getattr(self.module, self.name).iterator_class
+                                obj = iter(self.iterator_class(*args, **kwargs))
+                        except Exception as e:
+                            print
+                            traceback.print_exc()
+                        else:
+                            break
+                yield obj.next()
+
+        return wrapper()
+
diff --git a/talk/dls2012/demo/run.py b/talk/dls2012/demo/run.py
new file mode 100644
--- /dev/null
+++ b/talk/dls2012/demo/run.py
@@ -0,0 +1,15 @@
+from io import mplayer, view
+from process import process
+import sys
+
+if len(sys.argv) > 1:
+    video = mplayer(sys.argv[1])
+else:
+    video = mplayer()
+
+result = process(video)
+
+for img in result:
+    view(img)
+
+
diff --git a/talk/dls2012/demo/view.py b/talk/dls2012/demo/view.py
new file mode 100644
--- /dev/null
+++ b/talk/dls2012/demo/view.py
@@ -0,0 +1,6 @@
+from io import mplayer, view
+import sys
+
+for img in mplayer(sys.argv[1]):
+    view(img)
+


More information about the pypy-commit mailing list