Anton Anton - 3 months ago 8
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))