解决Numpy矩阵相减出现负值自动转正值的问题

栗子
栗子
发布时间:2026-10-13 | 5人浏览过
原创

在使用Numpy进行图像矩阵相减时,若未指定数据类型,默认uint8类型会导致负值自动转换为正值(如-1变为255)。本文通过分析错误代码与正确示例,指出通过设置dtype为np.int32或np.float64可解决此问题,确保计算结果准确。

问题描述与现象分析

问题描述

今日在使用Numpy执行矩阵减法运算时,发现部分本应显示为负数的位置被自动转换成了正数。

经观察,转换后的正值等于原负值加上256,具体表现如下:

以下是矩阵正常相减的示例:


>>> import numpy as np
>>> arr = np.array([98,100,103,161,192,210])
>>> brr = np.array([105,105,106,197,196,195])
>>> crr = arr-brr
>>> print(crr)
[ -7 -5 -3 -36 -4 15]

错误代码如下:


path = './image/Blur/blur5.png'
kernel_size = (21, 21);
sigma = 0;
img = cv2.imread(path)
img2gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2blur = cv2.GaussianBlur(img2gray, kernel_size, sigma);
grayMat = np.matrix(img2gray)
blurMat = np.matrix(img2blur)
finalMat = blurMat-grayMat
print(grayMat[0,0:10])
print(blurMat[0,0:10])
print(finalMat[0,0:10])

得到的结果值如下:


[[173 171 169 171 174 179 181 182 180 180]]
[[172 172 172 173 173 174 174 173 171 168]]
[[255 1 3 2 255 251 249 247 247 244]]

解决方案与代码修正

解决方案

上述矩阵相减结果自动转换的问题,源于直接通过grayMat = np.matrix(img2gray)创建矩阵。

此时得到的dtype类型为uint8,只需在初始化时指定为np.int32即可正常完成相减。即:

grayMat = np.matrix(img2gray ,dtype=np.float64)

补充知识:Python图像处理中的类型陷阱

补充知识:有关于python数字图像处理出现矩阵相减没有负数(值都在0-255)的情况分析

问题的发现:

近日在进行机器学习课程大作业时遇到瓶颈:在使用数字图像矩阵运算时,对两个参数矩阵进行相减(例如R通道值减去G通道值),测试结果始终为正数,且数值范围在0到255之间,这带来了诸多不便。

测试代码如下


print(imgs_train[1][:,:,1])
print("====================================")
print(imgs_train[1][:,:,2])
print("====================================")
print(imgs_train[1][:,:,1]-imgs_train[1][:,:,2])

输出结果为


[[141 143 144 ... 90 90 68]
 [139 141 141 ... 88 90 68]
 [140 141 140 ... 87 90 68]
 ...
 [ 52 52 52 ... 85 83 81]
 [ 52 52 52 ... 85 83 81]
 [ 52 52 52 ... 85 83 81]]
====================================
[[171 173 172 ... 106 107 84]
 [169 171 169 ... 106 107 86]
 [169 170 169 ... 107 109 88]
 ...
 [ 40 40 43 ... 68 66 64]
 [ 40 40 43 ... 68 66 64]
 [ 40 40 43 ... 68 66 64]]
====================================
[[226 226 228 ... 240 239 240]
 [226 226 228 ... 238 239 238]
 [227 227 227 ... 236 237 236]
 ...
 [ 12 12 9 ... 17 17 17]
 [ 12 12 9 ... 17 17 17]
 [ 12 12 9 ... 17 17 17]]

可以看出,尽管执行了矩阵相减,但理应为负值的元素却像取模运算一样变为了正数(即255加上计算结果)。导致这种情况的原因在于矩阵元素类型。默认情况下,此类矩阵类型为uint8(无符号8位整型),因此无法得出正确结果。

解决思路与验证

问题的解决

查阅相关资料后,发现可以通过设置元素格式进行运算,从而避免无负数结果的发生。

测试代码如下:


print(imgs_train[1][:,:,1])
print("====================================")
print(imgs_train[1][:,:,2])
print("====================================")
print(imgs_train[1][:,:,1].astype(np.float32)-imgs_train[1][:,:,2].astype(np.float32))

结果显示为:


[[141 143 144 ... 90 90 68]
 [139 141 141 ... 88 90 68]
 [140 141 140 ... 87 90 68]
 ...
 [ 52 52 52 ... 85 83 81]
 [ 52 52 52 ... 85 83 81]
 [ 52 52 52 ... 85 83 81]]
====================================
[[171 173 172 ... 106 107 84]
 [169 171 169 ... 106 107 86]
 [169 170 169 ... 107 109 88]
 ...
 [ 40 40 43 ... 68 66 64]
 [ 40 40 43 ... 68 66 64]
 [ 40 40 43 ... 68 66 64]]
====================================
[[-30. -30. -28. ... -16. -17. -16.]
 [-30. -30. -28. ... -18. -17. -18.]
 [-29. -29. -29. ... -20. -19. -20.]
 ...
 [ 12. 12. 9. ... 17. 17. 17.]
 [ 12. 12. 9. ... 17. 17. 17.]
 [ 12. 12. 9. ... 17. 17. 17.]]

综上所述,在遇到矩阵数值类型不明的情况下,可以指定其类型,之后矩阵元素便会以该数值类型进行计算。

以上这篇解决numpy矩阵相减出现的负值自动转正值的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表