J. Leung
J. Leung

Reputation: 95

Quick method to combine (x,y) pixel value of multiple images?

I have 10 1944 x 2546 binary images stored in a nparray images. I would like to read the pixel value of each pixel on the 10 images and combine them into a string of 0s and 1s (such as '1001101100') and store them into a 2D array output. So far I am using a nested for loop, which is very slow. Therefore, I wonder if there is any smarter approach to achieve the same result. My current code is as follow:

output = [()]
for y in range(0,image_height):
    for x in range(0,image_width):
        code_string = ''
        for n in range(0,len(images)-2):
            code_string = code_string + str(images[n][y,x]/255)
        output.append(code_string)

Upvotes: 3

Views: 615

Answers (3)

Paul Panzer
Paul Panzer

Reputation: 53029

You can do as follows:

# create 0, 255 arrays
imgs = [255 * np.random.randint(0, 2, (1944,2546)) for i in range(10)]

# binarize them, convert to int32, stack them along the last axis,
# add the offset of character '0' and view-cast to unicode
binstr = (np.r_[('2,3,0', *map(np.int32, map(np.bool8, imgs)))] + ord('0')).view('U10').squeeze()
binstr
# array([['0010110011', '0101011101', '0001000000', ..., '1011101100',
#         '1110011110', '0011110111'],
#        ['1101110100', '0000001000', '0000100101', ..., '0000110100',
#         '1000010011', '0001101011'],
#        ['0100011100', '0111101001', '0001011001', ..., '1111011111',
#         '0110100000', '0001111000'],
#        ...,
#        ['0100000110', '1000000000', '0000001011', ..., '1001110001',
#         '1001010000', '0010010111'],
#        ['0011100010', '0110010101', '0011111000', ..., '1011100101',
#         '1011001111', '1100011011'],
#        ['0011111101', '0000001101', '1110011011', ..., '1011110100',
#         '0001010010', '0001010010']], dtype='<U10')

Conversion takes half a second on my laptop.

Upvotes: 4

Antti A
Antti A

Reputation: 692

I think the slowest part is calling 10 x 1944 x 2546 append command.

You can reshape that images to shape (1944x2546, 10) table, and if you want to have list, use X.tolist() command at the end.

images_bool = images < 256
output = images_bool.transpose((1,2,0)).reshape((1944*2546,10)).tolist()

Why the conversion to the strings?

Upvotes: 0

Patrick Artner
Patrick Artner

Reputation: 51643

You might get a small speedup by not creating and appending to a string iteratively, but only once after gathering the bits across the images:

    code_string = []
    for n in range(0,len(images)-2):
        code_string.append(images[n][y,x]/255)
    output.append(''.join(code_string))

The probably better way would be to load the images into numpy-arrays and slice&dice them correctly - my numpyfu is not good enough for that.

Upvotes: 1

Related Questions