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