Scikit均值漂移算法返回黑色图片

时间:2017-09-24 17:32:06

标签: python

我正在尝试使用scikit均值移位算法执行图像分割。我使用opencv来显示分段图像。 我的问题如下:我使用不同示例中给出的代码,当我在分割后显示图像时,我得到一个黑色图像。我想知道是否有人能看出我的错误是什么...... 非常感谢您的帮助!

这是我的代码:

import numpy as np

import cv2

from sklearn.cluster import MeanShift, estimate_bandwidth

#Loading original image

originImg = cv2.imread('Swimming_Pool.jpg')


# Shape of original image

originShape = originImg.shape


# Converting image into array of dimension [nb of pixels in originImage, 3]

# based on r g b intensities

flatImg=np.reshape(originImg, [-1, 3])


# Estimate bandwidth for meanshift algorithm

bandwidth = estimate_bandwidth(flatImg, quantile=0.1, n_samples=100)

ms = MeanShift(bandwidth = bandwidth, bin_seeding=True)


# Performing meanshift on flatImg

ms.fit(flatImg)


# (r,g,b) vectors corresponding to the different clusters after meanshift

labels=ms.labels_


# Remaining colors after meanshift

cluster_centers = ms.cluster_centers_


# Finding and diplaying the number of clusters

labels_unique = np.unique(labels)

n_clusters_ = len(labels_unique)

print("number of estimated clusters : %d" % n_clusters_)


# Displaying segmented image

segmentedImg = np.reshape(labels, originShape[:2])

cv2.imshow('Image',segmentedImg)

cv2.waitKey(0)

cv2.destroyAllWindows()

3 个答案:

答案 0 :(得分:1)

您可以转换为其他颜色空间(例如,使用以下代码的Lab颜色空间),然后对颜色进行细分(舍弃强度)。

from skimage.color import rgb2lab
image = rgb2lab(image)

然后使用上面的代码来调整函数quantile的参数(n_samplesestimate_bandwidth()),最后使用matplotlib的{​​{1}}进行绘制分割后的图像如下图所示:

subplot

获得带有plt.figure() plt.subplot(121), plt.imshow(image), plt.axis('off'), plt.title('original image', size=20) plt.subplot(122), plt.imshow(np.reshape(labels, image.shape[:2])), plt.axis('off'), plt.title('segmented image with Meanshift', size=20) plt.show() 图片的以下输出。

enter image description here

答案 1 :(得分:0)

对于显示图像,正确的代码为

segmentedImg = cluster_centers[np.reshape(labels, originShape[:2])]
cv2.imshow('Image',segmentedImg.astype(np.uint8)
cv2.waitKey(0)
cv2.destroyAllWindows()

我在随机样本照片上尝试了您的分割方法,并且分割看起来很糟糕,可能是因为您的均值漂移仅在色彩空间上起作用,它会丢失局部信息。 python包skimage附带一个segmentation模块,它提供了一些超像素分割方法。 quickshift方法基于'模式搜索'机制,意味着交换基于。这些方法都不会分割出图像中的整个对象。它们提供了非常本地化的细分。

答案 2 :(得分:0)

问题是您要显示标签,您应该使用标签图将图像转换为超像素。

import numpy as np    
import cv2    
from sklearn.cluster import MeanShift, estimate_bandwidth

#Loading original image
originImg = cv2.imread('Swimming_Pool.jpg')

# Shape of original image    
originShape = originImg.shape


# Converting image into array of dimension [nb of pixels in originImage, 3]
# based on r g b intensities    
flatImg=np.reshape(originImg, [-1, 3])


# Estimate bandwidth for meanshift algorithm    
bandwidth = estimate_bandwidth(flatImg, quantile=0.1, n_samples=100)    
ms = MeanShift(bandwidth = bandwidth, bin_seeding=True)

# Performing meanshift on flatImg    
ms.fit(flatImg)

# (r,g,b) vectors corresponding to the different clusters after meanshift    
labels=ms.labels_

# Remaining colors after meanshift    
cluster_centers = ms.cluster_centers_    

# Finding and diplaying the number of clusters    
labels_unique = np.unique(labels)    
n_clusters_ = len(labels_unique)    
print("number of estimated clusters : %d" % n_clusters_)    

# Displaying segmented image    
segmentedImg = np.reshape(labels, originShape[:2])

superpixels=label2rgb(segmentedImg,originImg,kind="'avg'")

cv2.imshow('Image',superpixels)    
cv2.waitKey(0)    
cv2.destroyAllWindows()