Python 带有OpenCV的Numpy gradient()永远不会为负

Python 带有OpenCV的Numpy gradient()永远不会为负,python,opencv,numpy,Python,Opencv,Numpy,我一直在玩OpenCV和Numpy,我注意到当拍摄灰度图像的梯度时,它从来都不是负片。我还没有试过颜色。为什么会这样 import cv2 import numpy as np video_capture = cv2.VideoCapture(0) ret, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) Gx,Gy = np.gradient(gray) print "Gradient

我一直在玩OpenCV和Numpy,我注意到当拍摄灰度图像的梯度时,它从来都不是负片。我还没有试过颜色。为什么会这样

import cv2
import numpy as np

video_capture = cv2.VideoCapture(0)
ret, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

Gx,Gy = np.gradient(gray)
print "Gradient X"
print Gx[Gx<0]
print "\n\nGradient Y"
print Gy[Gy<0]

test_gx,test_gy = np.gradient(np.random.rand(10,10))
print "\n\nRandom Gradient X"
print test_gx[test_gx<0]
print "\n\nRandom Gradient Y"
print test_gy[test_gy<0]

默认情况下,来自摄影机的图像为无符号整数,因此它不能有负值。 尝试这样做:

Gx,Gy = np.gradient(gray.astype('float32'))

详细说明一下yhenon的回答 : 显然,无符号整数数组的梯度可能有负值。关键是
np.gradient(myarray)
myarray
的类型相同,因此它会将负值强制为高正值 :

>>> myarray = np.array([1,3,5,7,8,6,4,2], dtype='uint8')
>>> np.gradient(myarray)
array([   2. ,    2. ,    2. ,    1.5,  127.5,  126. ,  126. ,  254. ])
这种行为是一种缺陷,实际上和原则上都有缺陷

早期版本的解决方法确实是将输入转换为有符号整数类型,只是允许渐变本身为负值 :

>>> np.gradient(myarray.astype('int16'))
array([ 2. ,  2. ,  2. ,  1.5, -0.5, -2. , -2. , -2. ])

注意为了正确处理较大的变化,应至少转换为两倍大的类型-即
uint8
int16
uint32
int64
,等等。对于
numpy
错误修复,他们选择转换为
float64
,您的图像是空白的(即一种颜色)使梯度在任何地方都为0。这是一个灰度网络摄像头图像。Ben,你能给我们看一下
gray
中包含的精确图像吗?我在实际代码中测试它的图像是这样的,转换为灰度:精确图像是我网络摄像头中的实时灰度图像。
>>> np.gradient(myarray.astype('int16'))
array([ 2. ,  2. ,  2. ,  1.5, -0.5, -2. , -2. , -2. ])