skrhee
skrhee

Reputation: 357

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?

Upvotes: 5

Views: 3226

Answers (3)

racribeiro
racribeiro

Reputation: 93

Given 2 arrays p and q of bytes, I've sucessfully computed the difference using numpy with the following line of code.

r = (p>q)*(p-q)+(p<q)*(q-p)

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180540

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]

Upvotes: 5

too honest for this site
too honest for this site

Reputation: 12263

You should add tag image processing. That gave the idea. I think, the problem is that if you have something like 10-11 you get a value of 255, but would prefer to stick at 0, right?

That is called wrapping (strictly: modulo arithmetics, which is normal for fixed-size integer variables) and also applies to addition (255+1 wraps to 0).

What you want is called saturation arithmetics. This will avoid wrap-around by saturating the result to the minimum and maximum. Now, as I do not know numpy, I cannot tell you, if there is a saturated subtraction available, but that should be easy to find out for you.

Hope that my guess was right; your question leaves a lot of space for interpretation.

Upvotes: 1

Related Questions