Search code examples
pythonarraysopencvnumpysubtraction

Python array subtraction loops back to high number instead of giving negative value


Here is my code: I'm using numpy and opencv

q = np.array(image)
q = q.reshape(-1, q.shape[2])
r = np.subtract(q,p)
print r

Basically what happens is if the value in my q array is greater than p the subtraction loops back up to 256 and subtracts whats left from there. I'd rather get a value of 0 if the subtraction goes negative. Does anybody know a good way to do this?


Solution

  • You could change to int16 which supports negative integers and set neg values to 0, your values are wrapping because you have uint8's:

    arr1 = np.array([100, 200, 255],dtype=np.int16)
    arr2 = np.array([180, 210, 100],dtype=np.int16)
    
    sub_arr = np.subtract(arr1, arr2)
    sub_arr[sub_arr < 0] = 0
    print(sub_arr)
    [  0   0 155]
    

    To change you array you can use array.astype(np.int16) to change from uint8 to np.int16 and use the same to change back again after subtracting.

    arr1 = np.array([100, 200, 255],dtype=np.uint8)
    arr2 = np.array([180, 210, 100],dtype=np.uint8)
    _arr2 = arr2.astype(np.int16)
    sub_arr = np.subtract(arr1, _arr2)
    
    sub_arr[sub_arr < 0] = 0
    sub_arr = sub_arr.astype(np.uint8)
    print(sub_arr)
    

    Or also use np.clip:

    arr1 = np.array([100, 200, 255],dtype=np.uint8)
    arr2 = np.array([180, 210, 100],dtype=np.uint8)
    
    sub_arr = np.subtract(arr1, arr2.astype(np.int16)).clip(0, 255).astype(np.uint8)
    print(sub_arr)
    [  0   0 155]