OpenCV的扩张不同于scipy,matlab

OpenCV's dilate differs from scipy, matlab

import numpy as np
import cv2
import scipy.ndimage as sn

timg = np.array([[0,0,0,0],
                 [0,0,1,0],
                 [0,0,0,0],
                 [0,0,0,0]])

tker = np.array([[1,1,0],
                 [1,1,1],
                 [1,1,1]])

scipy.ndimage:

>>> print(sn.morphology.binary_dilation(timg,tker).astype(int))

[[0 1 1 0]
 [0 1 1 1]
 [0 1 1 1]
 [0 0 0 0]]

OpenCV:

>>> print(cv2.dilate(timg.astype(np.uint8), tker.astype(np.uint8)))

[[0 1 1 1]
 [0 1 1 1]
 [0 0 1 1]
 [0 0 0 0]]

似乎 ndimage 将内核放在图像的一个 1 像素上并将其膨胀到内核为 1 的任何地方,而 OpenCV 将内核放在每个像素上并将其设置为其邻居的最大值(当内核是 1).

哪种行为是正确的? Wikipedia's animation 似乎更喜欢 OpenCV。如果我调用了错误的函数,有什么方法可以用 scipy?

重现 OpenCV 的行为

旁注:

膨胀有两种不同的定义,它们的不同之处在于结构元素的镜像。两者都满足膨胀的所有性质,因此没有“正确”的方法来做到这一点。任一定义均有效。

这两个库使用了相反的膨胀定义。要从一个到另一个,镜像结构元素。注意在2D中,镜像和旋转180度是一样的:

tker = np.array([[1,1,0],
                 [1,1,1],
                 [1,1,1]])
tker2 = np.rot90(tker, 2)