ActiveState Code

Recipe 334971: Iterate Over Regions in a 2D Range


I use this iterator when I need to iterate over an image, working on regions or subsets of the image at a time. It returns regions from a 2D range, left to right, top to bottom.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def blocks(size, box=(1,1)):
    """
    Iterate over a 2D range in 2D increments.
    Returns a 4 element tuple of top left and bottom right coordinates.
    """
    box = list(box)
    pos = [0,0]
    yield tuple(pos + box)
    while True:
        if pos[0] >= size[0]-box[0]:
            pos[0] = 0
            pos[1] += box[1]
            if pos[1] >= size[1]:
                raise StopIteration
        else:
            pos[0] += box[0]
        topleft = pos
        bottomright = [min(x[1]+x[0],x[2]) for x in zip(pos,box,size)]
        yield tuple(topleft + bottomright)

if __name__ == "__main__":
    for c in blocks((100,100),(99,10)):
        print c
    for c in blocks((10,10)):
        print c

Discussion

The iterator will return a region from a 2D range of a specified size. If the region steps outside the 2D range, the region returned will be clipped to the 2D range.

Therefore the size of the region returned will not always be the same size.

Sign in to comment