# Looping over pixels in an image

I have the following code which iterates over all pixels of an image and does some manipulations on two images of the same size. I would like to speed it up and to avoid iterating over the positions in a for loop:

import numpy as np
import cv2

# Two images of same size
image_new = np.ones(image_in.shape[:2], dtype="uint8") * 255

counter = 0
counter2 = 0

for i in range(image_in.shape[0]):
for j in range(image_in.shape[1]):
if image_in[i, j] < 255:
counter += 1
if image_in2[i, j] == 0:
image_new[i, j] = 0
else:
image_new[i, j] = 255
counter2 += 1


How can I improve my code?

• I simply threshold my image. If the pixel values are greater of smaller then a threshold, the pixel value of a new image should be set to 0 or 1. Apr 23, 2018 at 12:21
• Do you really need counter and counter2? Apr 23, 2018 at 12:23
• Actually not, I could use np.count_nonzero on image_new at the end...Good point! Apr 23, 2018 at 12:31

I think the trick is trying to vectorise this as much as possible:

By the look of it, the code is trying to threshold at 0 and count pixels under 255.

We can change the first part of the loop to:

counter = np.sum(image_in < 255) # Sums work on binary values
counter2 = np.sum(np.bitwise_and(image_in < 255, image_in2 != 0))


And the second to:

# This is 0 or 1 depending on whether it is == 0
image_new[:,:] = (image_in2 != 0) # image_new[i,j] = (image_in2[i,j] != 0)

# So scale the values up with a simple multiplcation
image_new = image_new*255 # image_new[i,j] = image_new[i,j]*255

• But how do I get the value of the second counter, it should count only pixels with values of 255 where the same position of image2 has the value 0. Apr 23, 2018 at 13:02
• The rest of the image1 contain pixel with values of 255 but they should be excluded in the count. Apr 23, 2018 at 13:04
• Added counter2, this isn't the cleanest way of doing this but it works pretty efficiently Apr 23, 2018 at 13:06
• ~ 300x speed up, nice! Apr 23, 2018 at 14:00