Python simple nested for loops -
i trying simple nested loop in python scan threshold-ed image detect white pixels , store location. problem although array reading 160*120 (19200) still takes 6s execute, code follows , or guidance appreciated:
im = image.open('pygamepic') r, g, b = np.array(im).t x = np.zeros_like(b) height = len(x[0]) width = len(x) x[r > 120] = 255 x[g > 100] = 0 x[b > 100] = 0 row_array = np.zeros(shape = (19200,1)) col_array = np.zeros(shape = (19200,1)) z = 0 in range (0,width-1): j in range (0,height-1): if x[i][j] == 255: z = z+1 row_array[z] = col_array[z] = j
first, shouldn't take 6 seconds. trying code on 160x120 image takes ~0.2 s me.
that said, numpy
performance, want avoid loops. it's simpler vectorize along except smallest axis , loop along that, when possible should try @ once. makes things both faster (pushing loops down c) , easier.
your loop seems little strange me-- seem have off-by-one error both in terms of you're starting storing results (your first value placed in z=1
, not z=0
) , in terms of how far you're looking (range(0, x-1)
doesn't include x-1
, you're missing last row/column-- want range(x)
.)
if want indices r > 120
neither g > 100
nor b > 100
, there simpler approaches. can create boolean arrays. example, first can make dummy data:
>>> r = np.random.randint(0, 255, size=(8,8)) >>> g = np.random.randint(0, 255, size=(8,8)) >>> b = np.random.randint(0, 255, size=(8,8))
then can find places our condition met:
>>> (r > 120) & ~(g > 100) & ~(b > 100) array([[false, true, false, false, false, false, false, false], [false, false, true, false, false, false, false, false], [false, true, false, false, false, false, false, false], [false, false, false, true, false, true, false, false], [false, false, false, false, false, false, false, false], [false, true, false, false, false, false, false, false], [false, false, false, false, false, false, false, false], [false, false, false, false, false, false, false, false]], dtype=bool)
then can use np.where
coordinates:
>>> r_idx, c_idx = np.where((r > 120) & ~(g > 100) & ~(b > 100)) >>> r_idx array([0, 1, 2, 3, 3, 5]) >>> c_idx array([1, 2, 1, 3, 5, 1])
and can sanity-check these indexing r
, g
, , b
:
>>> r[r_idx, c_idx] array([166, 175, 155, 150, 241, 222]) >>> g[r_idx, c_idx] array([ 6, 29, 19, 62, 85, 31]) >>> b[r_idx, c_idx] array([67, 97, 30, 4, 50, 71])
Comments
Post a Comment