简体   繁体   中英

Iterate vertically on an image to get its pixel indexes

I am trying to iterate over the pixels in an image, but rather vertically instead of the normal horizontal way. Here is an example of a small-sized image I might have (I have images where the size is in the hundreds):

"""
Note: X represents pixels
Sample Image (3 x 4):

X X X X
X X X X
X X X X
"""

Clearly, to iterate over this image horizontally, it is easy to do so, as I have done here:

import itertools

width = range(3)
height = range(4)

print("Pixel positions:")
for pixel in itertools.product(width, height):
    print(*pixel)

Output:

Pixel positions:
0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3

These are the index positions of the pixels in the image (assume it as a large 2D list of pixels) but iterated horizontally. I want to be able to do the same but vertically . Is there an itertools function that allows me to do the same but column-wise? Here are the indexes for this sample image:

Column-wise:
0 0
1 0
2 0
0 1
1 1
2 1
0 2
1 2
2 2
0 3
1 3
2 3

I have attempted to reverse the positions with print(*pixel[::-1]) , however, this results in certain index positions that are out of range such as the last one from 2 3 to 3 2 . 3 2 is not valid as there aren't 3 rows (0, 1, 2 only). The same goes for other positions as well.

I would like a solution without the use of non-built-in libraries. Itertools is fine as I am using it for something else in my program.

Try this code:

width = range(3)
height = range(4)

print("Pixel positions:")
for x in height:
    for y in width:
        print(y, x)

Output:

Pixel positions:
0 0
1 0
2 0
0 1
1 1
2 1
0 2
1 2
2 2
0 3
1 3
2 3

To iterate horizontally just swap the two for-loops:

width = range(3)
height = range(4)

print("Pixel positions:")
for y in width:
    for x in height:
        print(y, x)

Performance comparison:

$ python -m timeit -n 100 '
width = range(1000)
height = range(1000)

for pixel in ((x, y) for y in height for x in width):
    pass
'
100 loops, best of 3: 104 msec per loop

Nested for-loop is about 8x faster:

$ python -m timeit -n 100 '
width = range(1000)
height = range(1000)

for y in width:
    for x in height:
        pass
'
100 loops, best of 3: 12.7 msec per loop

When also creating a tuple containing the result coordinates, the code is still 2x faster. But it is questionable if creating a tuple containing the coordinates is required for the task at hand.

$ python -m timeit -n 100 '
width = range(1000)
height = range(1000)

for y in width:
    for x in height:
        (x, y)
'
100 loops, best of 3: 52.5 msec per loop

According to the documentation, itertools.product(width, height) is equal to:

((x, y) for x in width for y in height)

If you want to iterate column-wise, just swap the inner loops:

for pixel in ((x, y) for y in height for x in width):
    print(*pixel)

0 0
1 0
2 0
0 1
1 1
2 1
0 2
1 2
2 2
0 3
1 3
2 3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM