Python数组减法循环回到高数值而不是给出负值

4

以下是我的代码: 我使用numpy和opencv

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

基本上,如果我的 q 数组中的值大于 p,则减法循环回到 256 并从那里减去剩下的部分。如果减法结果为负数,我宁愿得到一个值为 0。有人知道一个好方法吗?


你的问题不够清晰,你想要做什么? - Mazdak
“p”是什么意思?你说的“循环回路”是什么意思?是指类似于“0-1 = 256”的情况发生吗? - Francesco Montesano
我就是不明白为什么减法不起作用,我认为是发生了某种循环回路,但我不确定。p与q相同,只是从不同的文件中提取图像。 - skrhee
我没有遇到溢出错误,但是可能还是得到了一些值。这是我的第一个图像处理项目,所以我对它还不熟悉。 - skrhee
好的,在检查过后:假设我的 q 是 [x, 189, z] 假设我的 p 是 [m, 222, n]那么我的 r 就变成了 [x-m, 223, z-n]223 等于 256-33。 - skrhee
可能是numpy uint8像素包装解决方案的重复问题。 - Jim G.
3个回答

4

您可以改为使用支持负整数的 int16,并将负值设置为 0,因为您当前使用的是 uint8,所以您的值正在发生环绕:

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]

要更改数组,您可以使用array.astype(np.int16)将其从uint8更改为np.int16,并在减去后再次使用相同的方法更改回来。

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)

或者也可以使用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]

那么你确定在numpy中没有可用的饱和减法?嗯...这让我感到惊讶,因为这是相当常见且值得优化实现的。 - too honest for this site
@skrhee,不用担心,我远非numpy专家,所以可能有更好的方法,但这对我来说已经足够好了;) - Padraic Cunningham
1
@PadraicCunningham,这已经足够好了!祝你周末愉快。 - skrhee
@skrhee,你也一样,很高兴能帮到你。 - Padraic Cunningham
你是指“字符串还是数字”? - Padraic Cunningham

1
你应该添加图像处理标签。这给了我灵感。我认为,问题在于如果你有类似10-11这样的东西,你会得到255的值,但更愿意保持在0,对吗?
这被称为包装(严格来说是模算术,对于固定大小的整数变量来说很正常),也适用于加法(255+1包装为0)。
你想要的是饱和算术。这将通过将结果饱和到最小值和最大值来避免环绕。 现在,由于我不知道numpy,所以我不能告诉你是否有可用的饱和减法,但这对你来说应该很容易找到。
希望我的猜测是正确的;你的问题留下了很多解释的空间。

0

给定两个字节数组p和q,我已成功使用numpy计算了它们的差异,以下是代码行。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接