python - OpenCV的扩张不同于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]]
开放式简历:
>>> 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
(尽管我不希望它改变行为)
解决方案
膨胀有两种不同的定义,它们在结构元素的镜像方面有所不同。两者都满足膨胀的所有性质,因此没有“正确”的方法来做到这一点。任何一个定义都是有效的。
这两个库使用相反的膨胀定义。要从一个到另一个,镜像结构元素。请注意,在 2D 中,镜像与旋转 180 度相同:
tker = np.array([[1,1,0],
[1,1,1],
[1,1,1]])
tker2 = np.rot90(tker, 2)
推荐阅读
- azure - 在 Azure 存储中生成对容器和 blob 的匿名公共读取访问权限?
- arduino - 上传时编译错误或在arduino ide中验证
- scala - 在火花流中为 MQTT 创建自定义接收器
- java - 为什么不使用自定义构造函数推断变量记录组件?
- java - file.listRoots 不适用于 Java 中的便携式 USB 驱动器
- java - 片段上的动作模式背景问题
- c# - 带有颜色的日历可用日期
- firebase - 如何为firebase中的不同用户指定不同的权限?
- regular-language - 如果 L 和 L 补码是递归可枚举的,那么为什么 L 不能是正则语言?
- python - 在大型图像数据集中计算均方误差的最快方法是什么?