I'm working with a 2d array of "pixels" (rgb int tuples), and I need an efficient way to apply some numpy operations to each element. Specifically, I'm trying to find pixels within a few color shades of a goal colour to later isolate them with numpy.nonzero
Using For loops is for this case takes tens of seconds, so I'm looking to apply the numpy operations element-wise to achieve the same result.
I'm looking to apply
Tuple subtraction :
pixel_diff = numpy.subtract( pixel_a, pixel_b)
Tuple absolute value:
pixel_abs = numpy.abs( pixel_diff )
Tuple comparison:
pixel_bool = pixel_abs < int_tolerance
Tuple all ():
is_similar = numpy.all(pixel_bool)
Trying to apply any of these operations blindly to my array results in invalid promotion errors, so I figure there must be a proper way to do it, instead.
import numpy as np
#create a RGB array of 1000x1000x3 and separate into colors
R, G, B = np.random.randint(0, 255, size = (1000, 1000, 3))
#find all pixels less than 100, 100, 100
np.logical_and((R<100), (G<100), (B<100))
You may modify the last line to suit your color needs. As is, the last line takes about 1.5 ms on a single core.
You can convert into an equivalent non-structured view (without incurring any additional cost of making a copy of the underlying data):
my_3dview_of_ints = my_2d_of_3tuples.view(dtype=int)
where my_2d_of_3tuples
is your current structured array (array of tuples)
You can then perform your usual numpy array operations on this view without running into any type errors.
For example, if your array looks like this:
[[(207, 27, 185) ( 90, 197, 52) ( 58, 153, 145) (239, 42, 39)]
[(218, 23, 195) (226, 92, 170) ( 21, 114, 190) (192, 145, 48)]]
then the view, as created above, would look like this:
[[[207 27 185]
[ 90 197 52]
[ 58 153 145]
[239 42 39]]
[[218 23 195]
[226 92 170]
[ 21 114 190]
[192 145 48]]]
For example:
pixel_a = my_3dview_of_ints[0,0] # pixel [207,27,185] at [0,0]
pixel_b = my_3dview_of_ints[1,1] # pixel [226,92,170] at [1,1]
pixel_diff = numpy.subtract( pixel_a, pixel_b) # Gives [-12,-65,5]
You can even change specific elements in the view, and the changes would automatically reflect at the corresponding location in your original structured array:
my_3dview_of_ints[3,3] = pixel_a # Assign [207, 27,185] to location [3,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.