Malcolm Who
Malcolm Who

Reputation: 443

Fastest way to do per pixel calculations

I've been merging 2 lists:

RGB list from an image and a Pixel list from (y * w) of an image.

rgb_list, pixel_list

I do this by using zip:

rgb_pixel = [zip(rgb, _pixels)]

This will give me:

rgb_pixel = [[(255, 0, 255), (0, 1)], [(0, 0, 0), (0, 2)]]

The reason I do this is to eliminate the lists with

RGB == 0, 0, 0 

whilst getting the right x, y coordinates.

This is the code I use to remove the said coordinates:

non_blank_pixels = [i[1] for i in pixels if i[0] != (0, 0, 0)]

and this will yield to a list will only x, y coordinates that are "not-blank" or not having RGB of 0, 0, 0

Result:

non_blank_pixels = [(0, 2), (0, 3)..]

Full code:

rgb_list= tuple(zip(sct_img.raw[2::4], sct_img.raw[1::4], sct_img.raw[0::4]))
pixel_list= tuple((x, y) for y in range(height) for x in range(width))
rgb_pixel= tuple(zip(rgb, _pixels))
non_blank_pixels = [i[1] for i in pixels if i[0] != (0, 0, 0)]

This works, but with the 2-5 ms calculations, most of it is with this part:

pixel_list = tuple((x, y) for y in range(height) for x in range(width))

Is there a way that I can speed this up?

Upvotes: 0

Views: 142

Answers (1)

m.oulmakki
m.oulmakki

Reputation: 306

If the main goal is to have a list of non empty coordinates, then you only need to loop through your height * width pixels once.

First let's figure out how to get the RGB values for a given pixel from your sct_img.raw list. I'm making some assumptions here since I'm not familiar with how you parse your image. The math you'd need might be slightly different but the approach should remain relevant if my assumptions are incorrect.

My assumptions are that:

  • sct_img.raw is an array of (3widthheight) elements, where each triplet of elements represents the R G B values for the next pixel.
  • The first triplet describes pixel (0,0). The next triplet pixel (0,1) or in other words first row second column, etc.
  • this array stores the R value first, then the G, then the B, then the R of the next pixel etc.

This means that every 3 * width entries describe a row of pixels. This means that whenever we shift to the next row, we should shift by 3 * width elements in our array. In other words: row 0 is captured by all the elements from index 0 to (3 * width) - 1, row 1 is captured by all the elements from index 3 * width to (6 * width) - 1 etc.

From our assumptions we know that (sct_img.raw[0],sct_img.raw[1], sct_img.raw[2]) describe the pixel (0,0), and that the next 3, i.e (sct_img.raw[3],sct_img.raw[4], sct_img.raw[5]) will describe the pixel (0,1). As we move to the next column, we shift down by 3.

So we can develop a general formula. The R value for an arbitrary pixel at position (x, y) is going to be r_value = sct_image.raw[(x*3) + (y*3*width)]

Finally we can get to your pixel list now by simply checking if the pixel is not empty before adding it.

pixel_list = []
for x in range(width):
  for y in range(height):
    rgb = (sct_image.raw[(x*3) + (y*3*width)], sct_image.raw[(x*3) + (y*3*width) + 1], sct_image.raw[(x*3) + (y*3*width) + 2])
    pixel_list.append((x, y)) if rgb != (0, 0, 0)

# or as a one liner
pixel_list[(x, y) for x in range(width) for y in range(height) if (sct_image.raw[(x*3) + (y*3*width)], sct_image.raw[(x*3) + (y*3*width) + 1], sct_image.raw[(x*3) + (y*3*width) + 2]) != (0, 0, 0)]

Upvotes: 1

Related Questions