python - opencv ximgproc.slic 和 skimage segmentation.slic 有什么区别?
问题描述
我用opencv和skimage在同一张图片上运行SLIC(Simple Linear Iterative Clustering)超像素算法,但得到的结果不同,skimage slic结果更好,如下图所示。第一个是opencv SLIC,第二个是skimage SLIC。我有几个问题希望有人能提供帮助。
- 为什么opencv有参数'region_size'而skimage是'n_segments'?
- 是否需要转换为 LAB 和高斯模糊?
- 有什么技巧可以优化 opecv SLIC 结果吗?
====================================
- OpenCV SLIC
- Skimage SLIC
# Opencv
src = cv2.imread('pic.jpg') #read image
# gaussian blur
src = cv2.GaussianBlur(src,(5,5),0)
# Convert to LAB
src_lab = cv.cvtColor(src,cv.COLOR_BGR2LAB) # convert to LAB
# SLIC
cv_slic = ximg.createSuperpixelSLIC(src_lab,algorithm = ximg.SLICO,
region_size = 32)
cv_slic.iterate()
# Skimage
src = io.imread('pic.jpg')
sk_slic = skimage.segmentation.slic(src,n_segments = 256, sigma = 5)
使用以下代码生成的具有超像素质心的图像
# Measure properties of labeled image regions
regions = regionprops(labels)
# Scatter centroid of each superpixel
plt.scatter([x.centroid[1] for x in regions], [y.centroid[0] for y in regions],c = 'red')
但是少了一个超像素(左上角),我发现
len(regions)
是 64len(np.unique(labels))
而是 65 ,为什么?
解决方案
我不确定你为什么认为 skimage slic 更好(我维护 skimage!),但是:
- 不同的参数化在数学和计算机科学中很常见。无论您使用区域大小还是段数,都应该得到相同的结果。我希望在两者之间转换的公式类似于 n_segments = image.size / region_size。
- 原始论文建议,对于自然图像(即您所展示的真实世界的图像,而不是来自显微镜或天文学的图像),转换为 Lab 会产生更好的结果。
- 对我来说,根据您的结果,用于 scikit-image 的高斯模糊似乎高于用于 openCV。因此,您可以通过使用 sigma 使结果更加相似。我还认为两者之间的紧凑性参数可能并不相同。
推荐阅读
- node.js - 如何避免 webpack 生产构建中模块“bn.js”的重复?
- beautifulsoup - BeautifulSoup:如何只获得一部分
输出?
- c++ - 如果我在 C++ 程序中使用 2 个映射并且我用来在 2 个不同操作中存储它们的频率的键值是相同的怎么办?
- python - 尝试打印随机字符串时的回溯
- r - 如何解决与 R 中的 S4 对象相关的错误消息?
- asp.net-core - ASP.NET Core (!) 应用程序中出现奇怪的 .NET Framework (!) 错误
- javascript - Style.display = 'none' 不适用于 BBC.com 覆盖元素
- epplus - EPPlus 检测图像纵横比
- node.js - 使用 Node.js 加密流解密文件
- python - 如何从python中的列表中选择3个元素