我想执行一个简单的操作: b+g+r b,g,r 变量是整数并且值低于 256。我收到溢出警告和错误的结果。问题是操作很简单(结果不高于 765),我不应该收到溢出警告
这是我的代码:
import cv2 as cv
import numpy as np
imgname = 'r_hh_classic.png'
img = cv.imread(imgname)
h,w,_ = img.shape
for y in range(h):
for x in range(w):
b,g,r = img[y,x]
print(b,g,r,b+g+r) #print var b, var g, var r, and b+g+r
if b+g+r <= 382:
img[y,x] = 255-img[y,x,0], 255-img[y,x,1], 255-img[y,x,2]
cv.imshow('',img)
Python Shell:
Warning (from warnings module):
File "C:/Users/USER/AppData/Local/Programs/Python/Python310/!Saves/_images_/negate 2.py", line 14
print(b,g,r,b+g+r)
RuntimeWarning: overflow encountered in scalar add
165 159 191 3
Warning (from warnings module):
File "C:/Users/USER/AppData/Local/Programs/Python/Python310/!Saves/_images_/negate 2.py", line 15
if b+g+r <= 382:
RuntimeWarning: overflow encountered in scalar add
165 159 191 3
165 159 191 3
164 157 191 0
162 156 191 253
161 155 190 250
161 155 190 250
161 154 190 249
160 154 189 247
160 154 189 247
160 152 189 245
159 151 188 242
159 151 188 242
157 151 188 240
157 151 188 240
156 149 186 235
155 148 185 232
154 148 185 231
154 148 185 231
154 146 185 229
152 145 185 226
152 145 185 226
152 145 185 226
152 145 184 225
151 143 183 221
150 143 184 221
150 143 184 221
149 142 182 217
149 142 182 217
149 140 181 214
148 140 181 213
146 139 181 210
146 138 181 209
前 3 个数字是 b、g、r 和第 4 个是 b+g+r 但你可以看到,这是极其错误的
你的代码中出现溢出警告,是因为你正在对
cv2.imread()
返回的 NumPy 数组
执行操作。尽管你的图像在 0-255 的范围内具有值,但
cv2.imread()
加载的图像数据类型默认情况下为
uint8
(8 位无符号整数)。当
uint8
值的总和超过 255(
uint8
的最大值)时,就会发生溢出。
你可以通过以下两种方式解决此问题:
1. 在计算之前转换像素值:
在执行加法运算之前,将像素值从
uint8
转换为更大的数据类型(如
int
)。这将防止溢出。
```python import cv2 as cv import numpy as np
imgname = 'r_hh_classic.png' img = cv.imread(imgname)
h,w,_ = img.shape
for y in range(h): for x in range(w): b,g,r = img[y,x] print(b,g,r, b + g + r) # 在加法之前转换为 int if int(b) + int(g) + int(r) <= 382: img[y,x] = 255-img[y,x,0], 255-img[y,x,1], 255-img[y,x,2]
cv.imshow('',img) cv.waitKey(0) ```
2. 更改图像数据类型:
在读取图像时,将图像数据类型更改为
int
或更大的数据类型。
```python import cv2 as cv import numpy as np
imgname = 'r_hh_classic.png' # 以 int16 数据类型读取图像 img = cv.imread(imgname, cv.IMREAD_ANYDEPTH)
h,w,_ = img.shape
for y in range(h): for x in range(w): b,g,r = img[y,x] print(b,g,r,b+g+r) if b+g+r <= 382: img[y,x] = 255-img[y,x,0], 255-img[y,x,1], 255-img[y,x,2]
cv.imshow('',img) cv.waitKey(0) ```
这两种方法都可以防止溢出警告并给出正确的结果。选择哪种方法取决于你的具体需求和编码偏好。
标签:python,numpy,opencv,math,integer-arithmetic From: 76159083