2
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]]

开放式简历:

>>> 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 时)。

哪种行为是正确的?维基百科的动画似乎偏爱 OpenCV。如果我调用了错误的函数,有没有办法用 scipy 重现 OpenCV 的行为?

旁注:

  • matlab 表现得像 scipy
  • scipy 的行为也发生在 grey_dilation(尽管我不希望它改变行为)
4

1 回答 1

2

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

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

tker = np.array([[1,1,0],
                 [1,1,1],
                 [1,1,1]])
tker2 = np.rot90(tker, 2)
于 2018-06-03T20:37:11.657 回答