Anton Anton - 5 months ago 14
Python Question

Product of two equals numpy arrays are different

I'm facing very strange problem with arrays in python and numpy. First of all what Im trying to archive is :

1) Get an MxN matrix from KxTxN matrix
2) Transpose this matrix and calculate product of this transposed matrix and the original one

What I get is some what strange, here comes the code :

First of all, I have read an image with help of cv2, and got K by T by 3 matrix (a field of RGB points), then I'm cutting a small window form it and reshaping this window to M by N matrix :

def clipSubwindowFromImage(img, i, j, winSize):
winI = img[i - winSize: i + winSize + 1, j - winSize : j + winSize + 1, : ]
res = np.vstack((winI[:,::3,:].reshape(winI.shape[1],3), winI[:,1::3,:].reshape(winI.shape[1],3), winI[:,2::3,:].reshape(winI.shape[1],3)))
return res


so far so god, say we had
winSize = 1, i = 1, j = 1
and got a 9x3 matrix as a result: this matrix :

>> subWin = clipSubwindowFromImage(background12x12b, 1, 1, 1)
>> [[201 199 187]
[216 219 198]
[226 228 207]
[243 241 228]
[240 244 221]
[233 235 213]
[239 238 220]
[238 240 216]
[233 235 211]]


Then I just want to get the product in question, like this :

>>r1 = subWin.T.dot(subWin)
>>[[197 234 89]
[234 65 163]
[ 89 163 105]]


Well, it's not right, the right result should be :

>>[[477125 479466 438361]
[479466 481857 440483]
[438361 440483 402793]]


But if I initialize
subWin
manually like this :

>>subWin = np.array([[201, 199, 187], [216, 219, 198], [226, 228, 207], [243, 241, 228], [240, 244, 221], [233, 235, 213],[239, 238, 220], [238, 240, 216],[233, 235, 211]])


I get right result.

I can't get it,
subWin
is the SAME array in both cases (I checked it). Any ideas?

Answer

As @Aguy said, your problem comes from the data-type of your array. The dot product of a uint8 array with an other uint8 array gives an array that is also uint8 hence the data-type is overflowed in your case. Here's an example that shows the effect of overflow on your values:

import numpy as np

a = np.array([[201, 199, 187], [216, 219, 198], [226, 228, 207], [243, 241, 228], [240, 244, 221], [233, 235, 213],[239, 238, 220], [238, 240, 216],[233, 235, 211]]) 
b = a.T.dot(a)

print b.dtype
print b
print "overflowed uint8 :"
print b.astype(np.uint8)

Gives:

>>> int64
>>> [[477125 479466 438361]
>>>  [479466 481857 440483]
>>>  [438361 440483 402793]]
>>> overflowed uint8 :
>>> [[197 234  89]
>>>  [234  65 163]
>>>  [ 89 163 105]]

Just change the data-type of one array to something more suitable in your dot product and you're good to go :

r1 = subWin.T.dot(subWin.astype(np.uint32))