Python 解决cv2::filter2D()中负值的抑制问题

Python 解决cv2::filter2D()中负值的抑制问题,python,opencv,convolution,Python,Opencv,Convolution,我用卷积来计算图像中的梯度。为此,我使用了OpenCV的cv2.filter2D()函数,该函数是用Python实现的。我还编写了一个(缓慢的)实现,它简单地迭代所有像素。输入图像img是使用cv2.cvtColor()从RGB转换为YUV的.JPG图像,并使用OpenCV函数cv2.split()进行分割。我的代码(仅计算一个颜色通道)的摘要如下: 但是,filter2D似乎会从输入图像中修剪负值: 使用filter2D()的最大值:66 使用我的实现()的最大值:66 使用filter2D

我用卷积来计算图像中的梯度。为此,我使用了OpenCV的
cv2.filter2D()
函数,该函数是用Python实现的。我还编写了一个(缓慢的)实现,它简单地迭代所有像素。输入图像
img
是使用
cv2.cvtColor()
从RGB转换为YUV的.JPG图像,并使用OpenCV函数
cv2.split()
进行分割。我的代码(仅计算一个颜色通道)的摘要如下:

但是,filter2D似乎会从输入图像中修剪负值:

  • 使用filter2D()的最大值:66
  • 使用我的实现()的最大值:66
  • 使用filter2D()的最小值:0
  • 使用我的实现()的最小值:-146
使用翻转的内核
kernel=np.array([[1,2,1],[0,0,0],-1,-2,-1]])
结果如下:

  • 使用filter2D()的最大值:146
  • 使用我的实现()的最大值:146
  • 使用filter2D()的最小值:0
  • 使用我的实现()的最小值:-66
很明显,负值受到了抑制。
cv2.filter2D()
中的所有默认设置对我来说都很好,这就是我使用最小参数的原因。文件中没有提到这种行为,多个论坛建议不应压制负面价值观。有人知道为什么会发生这种情况,以及如何解决吗?我有一个变通办法,将内核和它的翻转变体的结果相加,但是对于一个简单的问题来说,这似乎是一个糟糕的解决方案

版本信息:

  • openCV
    4.4.0.44版
  • numpy
    1.19.2版
  • python
    3.8.5版

    • 解决方案在于输出的深度。通过将其设置为-1,输入图像的深度用于输出。由于输入图像很可能是uchar,因此饱和为0。通过使用以下方法将输出类型设置为cv2.CV_64F,可以解决饱和为零的问题:

      outputCV2=cv2.filter2D(img,cv2.CV_64F,内核)

      为了得到与outputMyImplementation完全相同的答案,内核必须翻转180度。但是,当查看绝对值时,不需要这样做,代码可以按所示使用

      imgYUV = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
      clr1, clr2, cl3 = cv2.split(imgYUV)
      (iH,iW) = clr1.shape[:2]
      pad=1
      paddedImg = cv2.copyMakeBorder(clr1,pad,pad,pad,pad,cv2.BORDER_REPLICATE)
      outputMyImplementation = np.zeros((iH,iW), dtype='int32')
      kernel = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
      for y in np.arange(pad, iH+pad):
          for x in np.arange(pad, iW+pad):
              roi = paddedImg[y-pad:y+pad+1, x-pad:x+pad+1]
              k = (roi*kernel).sum()
              outputMyImplementation[y-pad,x-pad] = k
      outputCV2 = cv2.filter2D(clr1,-1,kernel)