15

I wish to subtract 2 gray human faces from each other to see the difference, but I encounter a problem that subtracting e.g. [4] - [6] gives [254] instead of [-2] (or difference: [2]).

print(type(face)) #<type 'numpy.ndarray'>
print(face.shape) #(270, 270)
print(type(nface)) #<type 'numpy.ndarray'>
print(nface.shape) #(270, 270)

#This is what I want to do:
sface = face - self.nface #or
sface = np.subtract(face, self.nface)

Both don't give negative numbers but instead subtract the rest after 0 from 255.

Output example of sface:

[[  8 255   8 ...,   0 252   3]
 [ 24  18  14 ..., 255 254 254]
 [ 12  12  12 ...,   0   2 254]
 ..., 
 [245 245 251 ..., 160 163 176]
 [249 249 252 ..., 157 163 172]
 [253 251 247 ..., 155 159 173]]

My question: How do I get sface to be an numpy.ndarray (270,270) with either negative values after subtracting or the difference between each point in face and nface? (So not numpy.setdiff1d, because this returns only 1 dimension instead of 270x270)

Working

From the answer of @ajcr I did the following (abs() for showing subtracted face):

face_16 = face.astype(np.int16)
nface_16 = nface.astype(np.int16)
sface_16 = np.subtract(face_16, nface_16)
sface_16 = abs(sface_16)
sface = sface_16.astype(np.int8)
NumesSanguis
  • 5,832
  • 6
  • 41
  • 76
  • Can't replicate, if I create two numpy arrays full of values in the range 0-255 I can simply do `a - b` and it'll give me negative numbers. – Ffisegydd Oct 31 '14 at 15:29
  • 2
    Your array must be an unsigned integer type - try e.g. `dtype=np.int16`. – jonrsharpe Oct 31 '14 at 15:30

2 Answers2

19

It sounds like the dtype of the array is uint8. All the numbers will be interpreted as integers in the range 0-255. Here, -2 is equal to 256 - 2, hence the subtraction results in 254.

You need to recast the arrays to a dtype which supports negative integers, e.g. int16 like this ...

face = face.astype(np.int16)

...and then subtract.

Alex Riley
  • 169,130
  • 45
  • 262
  • 238
3

This is a problem with your datatype in the numpy array. You have a uint8 inside it, which seems to wrap around

Have a look at nfac.dtype whichwill show it to you. You have to convert it prior to your calculation operation. Use numpy.ndarray.astype to convert it or have a look at In-place type conversion of a NumPy array

Community
  • 1
  • 1
Sven
  • 710
  • 9
  • 18