python - numpy 2d array (coordinates) need to assign into 3D array, to some particular bin -


i have following code compute hog image 8 bins , pre-counted sobel x , y filtered image:

for y in xrange(0, 480):     x in xrange(0, 640):         base_angle = np.arctan2(sobel_y[y,x], sobel_x[y,x]) * 180/np.pi         if base_angle < 0: base_angle += 360         angle = int(round(base_angle / 45))         if angle == 8: angle = 0         hog[y,x,angle] += np.sqrt(sobel_x[y,x]**2 + sobel_y[y,x]**2) 

i trying modify avoid loops:

base_angle = np.arctan2(sobel_y, sobel_x) * 180/np.pi base_angle[base_angle < 0] += 360 angle =(base_angle / 45).round().astype(np.uint8) angle[angle == bins] = 0 hog[:,:,angle] += np.sqrt(sobel_x**2 + sobel_y**2) 

however, last expression not count correctly. need have magnitude (np.sqrt... expression) being added hog array according index angle array, @ every (y,x) point of hog array. solutions?

use

magnitude = np.sqrt(sobel_x**2 + sobel_y**2) y, x = np.ogrid[0:angle.shape[0], 0:angle.shape[1]] hog[y, x, angle] += magnitude 

to update hog.


import numpy np  def using_for_loop(hog, sobel_y, sobel_x):     y in xrange(0, sobel_y.shape[0]):         x in xrange(0, sobel_x.shape[1]):             base_angle = np.arctan2(sobel_y[y, x], sobel_x[y, x]) * 180 / np.pi             if base_angle < 0:                 base_angle += 360             angle = int(round(base_angle / 45))             if angle == 8:                 angle = 0             hog[y, x, angle] += np.sqrt(sobel_x[y, x] ** 2 +                                         sobel_y[y, x] ** 2)     return hog  def using_indexing(hog, sobel_y, sobel_x):     base_angle = np.arctan2(sobel_y, sobel_x) * 180 / np.pi     base_angle[base_angle < 0] += 360     angle = (base_angle / 45).round().astype(np.uint8)     angle[angle == bins] = 0     magnitude = np.sqrt(sobel_x ** 2 + sobel_y ** 2)     y, x = np.ogrid[0:angle.shape[0], 0:angle.shape[1]]     hog[y, x, angle] += magnitude     return hog  bins = 8 sobel_y, sobel_x = np.meshgrid([1, 2, 3], [4, 5, 6, 7]) # hog = np.zeros(sobel_x.shape + (bins,)) hog = np.random.random(sobel_x.shape + (bins,)) answer = using_for_loop(hog, sobel_y, sobel_x) result = using_indexing(hog, sobel_y, sobel_x) assert np.allclose(answer, result) 

note if

in [62]: angle.shape out[62]: (4, 3) 

then

in [74]: hog[:,:,angle].shape out[74]: (4, 3, 4, 3) 

that's not right shape. rather, if define

in [75]: y, x = np.ogrid[0:angle.shape[0], 0:angle.shape[1]] 

then hog[y, x, angle] has same shape magnitude:

in [76]: hog[y, x, angle].shape out[76]: (4, 3)  in [77]: magnitude = np.sqrt(sobel_x ** 2 + sobel_y ** 2)  in [78]: magnitude.shape out[78]: (4, 3) 

of course, not proof hog[y, x, angle] correct expression, equivalent of physicist's dimensionality check shows @ least on right track.


with numpy fancy indexing, when y, x, , angle have same shape (or broadcast same shape),

hog[y, x, angle] 

will of same shape. (i,j)th element in hog[y, x, angle] equal

hog[y[i,j], x[i,j], angle[i,j]] 

this why hog[y, x, angle] += magnitude works.


Comments