Commits

Hakan Ardo committed fdc87c9

use PixelIterator in demo as well

  • Participants
  • Parent commits 00106dd

Comments (0)

Files changed (5)

File talk/dls2012/demo/analytics.py

     def update(self, frame):
         self.background.update(frame)
         fg = foreground(frame, self.background.image)
+        find_objects(fg)
         #view(self.background.image)
-        for box in find_objects(fg):
-            box.draw(frame)
-        view(frame, 'result')
         view(255 * fg)
 

File talk/dls2012/demo/demo.py

         part1(vim)
     part2(vim, skip1)
 
+    runner.kill()
+
 def part1(vim):
 
     pause("We'r looking at the input and output of this Tracker object that\n" + 
         print >>fd, """
 from reloader import autoreload
 from io import view, viewsc
+from image import PixelIter
 
 def dilate(fg, r=1):
     res = fg.new()
     for x, y in fg.indexes():
         res[x, y] = fg[x, y]
-
-        for dx in xrange(-r, r+1):
-            for dy in xrange(-r, r+1):
-                res[x, y] = max(res[x, y], fg[x+dx, y+dy])
+        for dx, dy in PixelIter(xrange(-r, r+1), xrange(-r, r+1)):
+            res[x, y] = max(res[x, y], fg[x+dx, y+dy])
     return res
 
 @autoreload
     pause("That's a bit slow, but this operation is separable, let's see\n"+
           "if it is faster with two passes.")
     vim.send(':e detect.py<CR>')
-    vim.type('6ggix<ESC>9ggix<ESC>jjdd')
-    vim.send('<<')
-    vim.type('ix<ESC>9wix<ESC>13wxxx', 0.2)
-    vim.type('VkkkkkyP6jx')
-    vim.type('15ggx7wcwxres<ESC>')
+    vim.type('7ggix<ESC>9ggix<ESC>jddOfor dx in xrange(-r, r+1):<ESC>')
+    vim.type('11ggix<ESC>9wix<ESC>13wxxx', 0.2)
+    vim.type('VkkkkyP5jx', 0.2)
+    vim.type('14ggx7wcwxres<ESC>')
     vim.type('jbbbcwdy<ESC>jhx9wx6wcwxres<ESC>3wxxxllli+dy<ESC>:w<CR>', 0.2)
 
     pause("Now we need som erosion to thin out the objects again. Let's\n"+
           "generalize dilate make it implement both dilation and erotion")
-    vim.type('5ggwcwmorph<ESC>$hi<BS><BS>, fn<ESC>')
+    vim.type('6ggwcwmorph<ESC>$hi<BS><BS>, fn<ESC>')
     vim.type('11gg7wcwfn<ESC>', 0.2)
-    vim.type('17gg7wcwfn<ESC>', 0.2)
-    vim.type('20ggOdef dilate(fg, r=1):<CR>return morph(fg, r, max)<CR>')
+    vim.type('16gg7wcwfn<ESC>', 0.2)
+    vim.type('19ggOdef dilate(fg, r=1):<CR>return morph(fg, r, max)<CR>')
     vim.type('<CR>def erode(fg, r=1):<CR>return morph(fg, r, min)<CR><ESC>')
-    vim.type('28ggwwierode(<ESC>A, 4)<ESC>:w<CR>')
+    vim.type('G27ggwwierode(<ESC>A, 4)<ESC>:w<CR>')
 
     pause("That's all! Feel free to make your own adjustments or (to quit),")
 
 
-    runner.kill()
 if __name__ == '__main__':
     demo(*map(eval, sys.argv[1:]))

File talk/dls2012/demo/detect.py

+
 from reloader import autoreload
 from io import view, viewsc
-
-def morph(fg, r, fn):
-    res = fg.new()
-    for y in xrange(fg.height):
-        for x in xrange(fg.width):
-            #res[x, y] = max(fg[x+dx, y+dy] 
-            #                for dx in xrange(-r, r+1) 
-            #                for dy in xrange(-r, r+1))
-            res[x, y] = fg[x, y]
-            for dx in xrange(-r, r+1):
-                for dy in xrange(-r, r+1):
-                    res[x, y] = fn(res[x, y], fg[x+dx, y+dy])
-    return res
+from image import PixelIter
 
 def morph(fg, r, fn):
     xres = fg.new()
             res[x, y] = fn(res[x, y], xres[x, y+dy])
     return res
 
+def dilate(fg, r=1):
+    return morph(fg, r, max)
+
 def erode(fg, r=1):
     return morph(fg, r, min)
 
-def dilate(fg, r=1):
-    return morph(fg, r, max)
+@autoreload
+def find_objects(fg):
+    seg = erode(dilate(fg, 3), 4)
+    viewsc(seg, 'segments')
 
-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 renumber(self):
-        ll = list(set(self.labels))
-        ll.sort()
-        if ll[0] != 0:
-            ll.insert(0, 0)
-        for x, y in self.labels.indexes():
-            self.labels[x, y] = ll.index(self.labels[x, y])
-        self.last_label = len(ll) - 1
-
-
-def bwlabel(seg):
-    labels = Labler(seg)
-    while not labels.done:
-        labels.done = True
-        for x, y in seg.indexes():
-            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 x, y in reversed(seg.indexes()):
-            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)
-    labels.renumber()
-    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 x, y in labels.indexes():
-        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, minarea=100):
-    seg = erode(dilate(fg, 3), 4)
-    labels = bwlabel(seg)
-    boxes = extract_boxes(labels)
-    boxes = [b for b in boxes if b.area() >= minarea]
-    viewsc(labels, 'segments')
-    return boxes

File talk/dls2012/demo/image.py

         return iter(self.data)
 
     def indexes(self):
-        return PixelIter(self.width, self.height)
+        return PixelIter(xrange(self.width), xrange(self.height))
 
 class ConstantImage(Image):
     def __init__(self, w, h, value):
         raise TypeError('ConstantImage does not support item assignment')
 
 class PixelIter(object):
-    def __init__(self, w, h, rev=False):
-        self.width, self.height, self.rev = w, h, rev
+    def __init__(self, range_x, range_y, rev=False):
+        self.range_x, self.range_y, self.rev = range_x, range_y, rev
         if rev:
-            self.iter_x = reversed(xrange(w))
-            self.iter_y = reversed(xrange(h))
+            self.iter_x = reversed(self.range_x)
+            self.iter_y = reversed(self.range_y)
         else:
-            self.iter_x = iter(xrange(w))
-            self.iter_y = iter(xrange(h))
+            self.iter_x = iter(self.range_x)
+            self.iter_y = iter(self.range_y)
         self.y = self.iter_y.next()
 
     def next(self):
         except StopIteration:
             self.y = self.iter_y.next()
             if self.rev:
-                self.iter_x = reversed(xrange(self.width))
+                self.iter_x = reversed(self.range_x)
             else:
-                self.iter_x = iter(xrange(self.width))
+                self.iter_x = iter(self.range_x)
             x = self.iter_x.next()
         return x, self.y
 
         return self
 
     def __reversed__(self):
-        return PixelIter(self.width, self.height, not self.rev)
+        return PixelIter(self.range_x, self.range_y, not self.rev)
 
 def test_image():
     img = Image(10, 20)

File talk/dls2012/demo/io.py

 def viewsc(img, name='default'):
     view(img, name, True)
 
+