10
\$\begingroup\$

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_in = cv2.imread('my_image.png') image_in2 = cv2.imread('my_image2.png') 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?

\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Apr 23, 2018 at 12:21
  • 1
    \$\begingroup\$ Do you really need counter and counter2? \$\endgroup\$ Commented Apr 23, 2018 at 12:23
  • \$\begingroup\$ Actually not, I could use np.count_nonzero on image_new at the end...Good point! \$\endgroup\$ Commented Apr 23, 2018 at 12:31

1 Answer 1

8
\$\begingroup\$

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 
\$\endgroup\$
4
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Apr 23, 2018 at 13:02
  • \$\begingroup\$ The rest of the image1 contain pixel with values of 255 but they should be excluded in the count. \$\endgroup\$ Commented Apr 23, 2018 at 13:04
  • 2
    \$\begingroup\$ Added counter2, this isn't the cleanest way of doing this but it works pretty efficiently \$\endgroup\$ Commented Apr 23, 2018 at 13:06
  • 2
    \$\begingroup\$ ~ 300x speed up, nice! \$\endgroup\$ Commented Apr 23, 2018 at 14:00

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.