我正在实施Harris角点检测并出现溢出错误:
harris.py:27: RuntimeWarning: overflow encountered in ubyte_scalars
Mat[0][1]=Ix[i][j]*Iy[i][j]
harris.py:28: RuntimeWarning: overflow encountered in ubyte_scalars
Mat[1][0]=Ix[i][j]*Iy[i][j]
这是完整的源代码。错误来自哪里?由于Ix.max为255且min为0。
import cv2
import numpy as np
im=cv2.imread('image.png', cv2.CV_LOAD_IMAGE_GRAYSCALE)
(M,N)=im.shape
print M
print N
Gx=np.array([[1, 0, -1],[ 2, 0, -2], [1, 0, -1]])
Gy=np.array([[1, 2, 1],[0, 0, 0],[-1, -2, -1]])
Ix=cv2.filter2D(im, -1, Gx)
Iy=cv2.filter2D(im, -1, Gy)
print np.max(Ix)
print np.min(Ix)
print np.max(Iy)
print np.min(Iy)
Mat=np.zeros((2,2), dtype='float64')
R=np.zeros((M,N), dtype='float64')
for i in range(M):
for j in range(N):
Mat[0][0]=Ix[i][j]**2
Mat[0][1]=Ix[i][j]*Iy[i][j]
Mat[1][0]=Ix[i][j]*Iy[i][j]
Mat[1][1]=Iy[i][j]**2
R[i][j]=np.linalg.det(Mat)-(np.matrix.trace(Mat))**2
cv2.imshow("Ix",Ix)
cv2.imshow("Iy",Iy)
cv2.imshow("R",R)
cv2.waitKey(0)
答案 0 :(得分:4)
正在发生的事情是您的输入数据为uint8
。因为您将两个uint8
相乘,所以结果为uint8
,即使将其分配给float数组Mat
中的项目时也会上升。
举个例子:
In [1]: import numpy as np
In [2]: np.uint8(255) * np.uint8(255)
./anaconda/bin/ipython:1: RuntimeWarning: overflow encountered in ubyte_scalars
Out[2]: 1
请注意numpy会很高兴地返回结果(1
),但如果你不熟悉有限精度的整数,那就不是你所期望的。
较新版本的numpy引发运行时警告,而旧版本允许它以静默方式发生。
这是故意的行为。处理大型数组时,非常非常有用。您只需要注意,当涉及到有限精度的数据类型时,numpy的行为与C类似。
您有几种选择。
Ix, Iy = Ix.astype(float), Iy.astype(float)
。Ix[i][j]
和Iy[i][j]
投射到循环内的浮动内。