Steven
Steven

Reputation: 1173

Splitting a value with multiple bins numpy histogram

I'm trying to program the process on this image:

enter image description here

On the image the 2 on the right-side is mapped to bin "80" since its corresponding value on the left-side is 80. The 4 on the right-side however has a corresponding value of 10 on the left-side, and because there is no bin for 10, the 4 needs to get split into two values.

To accomplish this I am using numpy's histogram with the "weight" parameter like this:

t1 = [80, 10]
t2 = [2, 4]
bins = np.arange(0, 200, 20)

h = np.histogram(t1,bins=bins,weights=t2)

The 2 gets mapped correctly, but the 4 gets mapped entirely to bin 0 (leftmost).

Output:

 [4 0 0 0 2 0 0 0 0]

I think is due to the fact that the first bin is responsible for all directions in a range (0 to 20), instead of giving the magnitude when the direction doesn't equal to the exact same number as the bin.

So, I was wondering if anybody knows how I can rewrite this so the output will be:

 [2 2 0 0 2 0 0 0 0]

Upvotes: 3

Views: 1026

Answers (2)

John
John

Reputation: 329

Refer to Roy Jevnisek's answer, minlength should be 9 as there are 9 bins.

Also, since 180 degree is equivalent to 0 degree, the last element of h should be omitted and treated as the first element of h, as both the first and last elements of h represent the weighted count of 0 degree, ie:

h[0] = h[-1]
h = h[:-1]

Then the HOG can be plotted by:

GD = GD.reshape(-1)
GM = GM.reshape(-1)

w1 = (GD / 20) - np.floor(GD / 20)
w2 = np.ceil(GD / 20) - (GD / 20)

h1 =  np.bincount(np.floor(GD / 20).astype('int32'), GM * w2, minlength=9)  
h2 = np.bincount(np.ceil(GD / 20).astype('int32'), GM * w1, minlength=9)

h = h1 + h2
h[0] = h[-1]
h = h[:-1]
values = np.unique(np.floor(GD / 20).astype(np.int64))[:-1]
plt.title('Histogram of Oriented Gradients (HOG)')
plt.bar(values, h)
plt.show()

Upvotes: 1

Roy Jevnisek
Roy Jevnisek

Reputation: 320

Let's consider an easier task first: Assume you would want to quantize the gradient direction (GD) as follows: floor(GD/20). You could use the following:

h =  np.bincount(np.floor(GD.reshape((-1)) / 20).astype(np.int64), GM.reshape((-1)).astype(np.float64), minlength=13)

Where np.bincount simply accumulates the gradient magnitude (GM) based on the quantized gradient direction (GD). Notice that binlength controls the length of the histogram and it equals ceil(255/20).

However, you wanted soft assignment so you have to weight the GM contribution, you might want to try:

GD = GD.reshape((-1))
GM = GM.reshape((-1))

w = ((GD / 20) - np.floor(GD / 20)).astype(np.float64)
h1 =  np.bincount(np.floor(GD / 20).astype(np.int64), GM.astype(np.float64) * (1.0-w), minlength=13)  
h2 = np.bincount(np.ceil(GD / 20).astype(np.int64), GM.astype(np.float64) * w, minlength=13)
h = h1 + h2

p.s one might want to consider the np.bincount documentation https://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html

Upvotes: 4

Related Questions