[pypy-commit] extradoc extradoc: use a pixel iterator instead of nested loops

hakanardo noreply at buildbot.pypy.org
Thu Sep 13 17:10:04 CEST 2012


Author: Hakan Ardo <hakan at debian.org>
Branch: extradoc
Changeset: r4808:e980c8629157
Date: 2012-09-13 17:09 +0200
http://bitbucket.org/pypy/extradoc/changeset/e980c8629157/

Log:	use a pixel iterator instead of nested loops

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
@@ -16,17 +16,15 @@
 
 def morph(fg, r, fn):
     xres = fg.new()
-    for y in xrange(fg.height):
-        for x in xrange(fg.width):
-            xres[x, y] = fg[x, y]
-            for dx in xrange(-r, r+1):
-                xres[x, y] = fn(xres[x, y], fg[x+dx, y])
+    for x, y in fg.indexes():
+        xres[x, y] = fg[x, y]
+        for dx in xrange(-r, r+1):
+            xres[x, y] = fn(xres[x, y], fg[x+dx, y])
     res = fg.new()
-    for y in xrange(fg.height):
-        for x in xrange(fg.width):
-            res[x, y] = xres[x, y]
-            for dy in xrange(-r, r+1):
-                res[x, y] = fn(res[x, y], xres[x, y+dy])
+    for x, y in fg.indexes():
+        res[x, y] = xres[x, y]
+        for dy in xrange(-r, r+1):
+            res[x, y] = fn(res[x, y], xres[x, y+dy])
     return res
 
 def erode(fg, r=1):
@@ -61,17 +59,15 @@
     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 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 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)
+        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)
 
     return labels.labels
 
@@ -98,13 +94,12 @@
 
 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)
+    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()
 
 
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
@@ -68,6 +68,9 @@
     def __iter__(self):
         return iter(self.data)
 
+    def indexes(self):
+        return PixelIter(self.width, self.height)
+
 class ConstantImage(Image):
     def __init__(self, w, h, value):
         self.width = w
@@ -80,6 +83,34 @@
     def __setitem__(self, (x, y), 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
+        if rev:
+            self.iter_x = reversed(xrange(w))
+            self.iter_y = reversed(xrange(h))
+        else:
+            self.iter_x = iter(xrange(w))
+            self.iter_y = iter(xrange(h))
+        self.y = self.iter_y.next()
+
+    def next(self):
+        try:
+            x = self.iter_x.next()
+        except StopIteration:
+            self.y = self.iter_y.next()
+            if self.rev:
+                self.iter_x = reversed(xrange(self.width))
+            else:
+                self.iter_x = iter(xrange(self.width))
+            x = self.iter_x.next()
+        return x, self.y
+
+    def __iter__(self):
+        return self
+
+    def __reversed__(self):
+        return PixelIter(self.width, self.height, not self.rev)
 
 def test_image():
     img = Image(10, 20)


More information about the pypy-commit mailing list