使用 DBSCAN 无法正确分割图像

Posted

技术标签:

【中文标题】使用 DBSCAN 无法正确分割图像【英文标题】:Image not segmenting properly using DBSCAN 【发布时间】:2017-03-01 18:27:46 【问题描述】:

我正在尝试使用 scikitlearn 中的 DBSCAN 根据颜色分割图像。我得到的结果是。如您所见,有 3 个集群。我的目标是将图片中的浮标分成不同的集群。但显然它们显示为同一个集群。我尝试了各种 eps 值和 min_samples ,但这两件事总是聚集在一起。我的代码是:

img= cv2.imread("buoy1.jpg) 
labimg = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)

n = 0
while(n<4):
    labimg = cv2.pyrDown(labimg)
    n = n+1

feature_image=np.reshape(labimg, [-1, 3])
rows, cols, chs = labimg.shape

db = DBSCAN(eps=5, min_samples=50, metric = 'euclidean',algorithm ='auto')
db.fit(feature_image)
labels = db.labels_

plt.figure(2)
plt.subplot(2, 1, 1)
plt.imshow(img)
plt.axis('off')
plt.subplot(2, 1, 2)
plt.imshow(np.reshape(labels, [rows, cols]))
plt.axis('off')
plt.show()

我假设这是取欧几里得距离,因为它在实验室空间中的欧几里得距离在不同颜色之间会有所不同。如果有人能给我这方面的指导,我将不胜感激。

更新: 以下答案有效。由于 DBSCAN 需要一个不超过 2 维的数组,我将列连接到原始图像并重新整形以生成一个 n x 5 矩阵,其中 n 是 x 维度乘以 y 维度。这似乎对我有用。

indices = np.dstack(np.indices(img.shape[:2]))
xycolors = np.concatenate((img, indices), axis=-1) 
np.reshape(xycolors, [-1,5])

【问题讨论】:

您能在答案中添加完整的代码吗?我无法理解我在哪里添加对你有用的那 3 行 【参考方案1】:

您需要同时使用颜色和位置

现在,您只使用颜色。

【讨论】:

你能详细说明你的答案吗?为什么颜色不够? 因为您对像素形成区域感兴趣,否则您可能会得到嘈杂的结果。【参考方案2】:

您能否在答案中添加完整代码?我无法理解在哪里添加对您有用的那 3 行 – user8306074 Sep 4 at 8:58

让我为你解答,这里是完整版的代码:

import numpy as np
import cv2
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN

img= cv2.imread('your image') 
labimg = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)

n = 0
while(n<4):
    labimg = cv2.pyrDown(labimg)
    n = n+1

feature_image=np.reshape(labimg, [-1, 3])
rows, cols, chs = labimg.shape

db = DBSCAN(eps=5, min_samples=50, metric = 'euclidean',algorithm ='auto')
db.fit(feature_image)
labels = db.labels_

indices = np.dstack(np.indices(labimg.shape[:2]))
xycolors = np.concatenate((labimg, indices), axis=-1) 
feature_image2 = np.reshape(xycolors, [-1,5])
db.fit(feature_image2)
labels2 = db.labels_

plt.figure(2)
plt.subplot(2, 1, 1)
plt.imshow(img)
plt.axis('off')

# plt.subplot(2, 1, 2)
# plt.imshow(np.reshape(labels, [rows, cols]))
# plt.axis('off')

plt.subplot(2, 1, 2)
plt.imshow(np.reshape(labels2, [rows, cols]))
plt.axis('off')
plt.show()

【讨论】:

以上是关于使用 DBSCAN 无法正确分割图像的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 matplotlib 无法正确显示 CIFAR-10 图像?

Vue DOM 图像无法正确显示

使用 Jcrop,更改图像时无法正确刷新预览窗格

使用“flex:shrink”无法正确调整图像大小

裁剪图像后无法正确显示

JCrop 无法正确裁剪图像