Author: Hakan Ardo <[email protected]>
Branch: extradoc
Changeset: r4805:8cd898766245
Date: 2012-09-13 11:18 +0200
http://bitbucket.org/pypy/extradoc/changeset/8cd898766245/

Log:    object detection and bouding boxes

diff --git a/talk/dls2012/demo/analytics.py b/talk/dls2012/demo/analytics.py
--- a/talk/dls2012/demo/analytics.py
+++ b/talk/dls2012/demo/analytics.py
@@ -13,6 +13,8 @@
         self.background.update(frame)
         fg = foreground(frame, self.background.image)
         #view(self.background.image)
-        find_objects(fg)
+        for box in find_objects(fg):
+            box.draw(frame)
+        view(frame, 'result')
         view(255 * fg)
 
diff --git a/talk/dls2012/demo/detect.py b/talk/dls2012/demo/detect.py
--- a/talk/dls2012/demo/detect.py
+++ b/talk/dls2012/demo/detect.py
@@ -1,5 +1,5 @@
 from reloader import autoreload
-from io import view
+from io import view, viewsc
 
 def morph(fg, r, fn):
     res = fg.new()
@@ -35,7 +35,84 @@
 def dilate(fg, r=1):
     return morph(fg, r, max)
 
+class Labler(object):
+    def __init__(self, seg):
+        self.labels = seg.new()
+        self.last_label = 0
+        self.done = False
+
+    def update(self, x, y, neighbours):
+        neighbours = set(neighbours)
+        neighbours.discard(0)
+        if not neighbours:
+            self.last_label += 1
+            l = self.last_label
+        else:
+            l = min(neighbours)
+        if self.labels[x, y] != l:
+            self.done = False
+        self.labels[x, y] = l
+
+    def __getitem__(self, (x, y)):
+        return self.labels[x, y]
+
+
+def bwlabel(seg):
+    labels = Labler(seg)
+    while not labels.done:
+        labels.done = True
+        for y in xrange(seg.height):
+            for x in xrange(seg.width):
+                if seg[x, y]:
+                    ll = [labels[x, y], labels[x-1, y], labels[x-1, y-1], 
labels[x, y-1], labels[x+1, y-1]]
+                    labels.update(x, y, ll)
+
+        for y in reversed(xrange(seg.height)):
+            for x in reversed(xrange(seg.width)):
+                if seg[x, y]:
+                    ll = [labels[x, y], labels[x+1, y], labels[x-1, y+1], 
labels[x, y+1], labels[x+1, y+1]]
+                    labels.update(x, y, ll)
+
+    return labels.labels
+
+class BoundingBox(object):
+    maxx = maxy = float('-Inf')
+    minx = miny = float('Inf')
+
+    def add(self, x, y):
+        self.maxx = max(self.maxx, x)
+        self.maxy = max(self.maxy, y)
+        self.minx = min(self.minx, x)
+        self.miny = min(self.miny, y)
+
+    def draw(self, img):
+        for y in xrange(self.miny, self.maxy + 1):
+            img[self.maxx, y] = 255
+            img[self.minx, y] = 255
+        for x in xrange(self.minx, self.maxx + 1):
+            img[x, self.miny] = 255
+            img[x, self.maxy] = 255
+
+    def area(self):
+        return (self.maxx - self.minx + 1) * (self.maxy - self.miny + 1)
+
+def extract_boxes(labels):
+    boxes = {}
+    for y in xrange(labels.height):
+        for x in xrange(labels.width):
+            l = labels[x, y]
+            if l:
+                if l not in boxes:
+                    boxes[l] = BoundingBox()
+                boxes[l].add(x, y)
+    return boxes.values()
+
+
 @autoreload
-def find_objects(fg):
+def find_objects(fg, minarea=100):
     seg = erode(dilate(fg, 3), 4)
-    view(255*seg, 'd')
+    labels = bwlabel(seg)
+    boxes = extract_boxes(labels)
+    boxes = [b for b in boxes if b.area() >= minarea]
+    view(64*labels, 'segments')
+    return boxes
diff --git a/talk/dls2012/demo/image.py b/talk/dls2012/demo/image.py
--- a/talk/dls2012/demo/image.py
+++ b/talk/dls2012/demo/image.py
@@ -65,6 +65,9 @@
     def __nonzero__(self):
         return all(self.data)
 
+    def __iter__(self):
+        return iter(self.data)
+
 class ConstantImage(Image):
     def __init__(self, w, h, value):
         self.width = w
diff --git a/talk/dls2012/demo/io.py b/talk/dls2012/demo/io.py
--- a/talk/dls2012/demo/io.py
+++ b/talk/dls2012/demo/io.py
@@ -37,6 +37,7 @@
 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')
@@ -58,11 +59,23 @@
         assert self.height == img.height
         img.data.tofile(self.mplayer.stdin)
 
+    def viewsc(self, img):
+        a, b = min(img), max(img)
+        if a == b:
+            b += 1
+        self.view((img - a) * 255 / (b - a))
+
 viewers = {}
-def view(img, name='default'):
+def view(img, name='default', scale=False):
     try:
         viewer = viewers[name]
     except KeyError:
         viewer = viewers[name] = MplayerViewer()
-    viewer.view(img)
-    
+    if scale:
+        viewer.viewsc(img)
+    else:
+        viewer.view(img)
+
+def viewsc(img, name='default'):
+    view(img, name, True)
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to