我正在尝试使用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()
答案 0 :(得分:1)
您可以转换为其他颜色空间(例如,使用以下代码的Lab
颜色空间),然后对颜色进行细分(舍弃强度)。
from skimage.color import rgb2lab
image = rgb2lab(image)
然后使用上面的代码来调整函数quantile
的参数(n_samples
和estimate_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()
图片的以下输出。
答案 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()