【问题标题】:Scikit mean shift algorithm returns black pictureScikit均值移位算法返回黑色图片
【发布时间】:2018-03-05 16:43:38
【问题描述】:

我正在尝试使用 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()

【问题讨论】:

  • 对不起格式代码错误,不知道怎么写正确。
  • 编辑器中有一个按钮可以格式化为代码

标签: python image-processing scikit-learn scikit-image mean-shift


【解决方案1】:

问题是您正在尝试显示标签,您应该使用标签映射将图像转换为超像素。

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()

【讨论】:

    【解决方案2】:

    您可以转换为其他颜色空间(例如,Lab 颜色空间,使用以下代码)并对颜色进行分段(丢弃强度)。

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

    然后使用上面的代码调整函数estimate_bandwidth()的参数(quantilen_samples),最后使用matplotlibsubplot绘制分割后的图像,如下所示:

    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()
    

    使用pepper 图像获得以下输出。

    【讨论】:

      【解决方案3】:

      对于显示图像,正确的代码应该是

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

      我在随机样本照片上尝试了您的分割方法,但分割看起来很糟糕,可能是因为您的均值偏移仅适用于颜色空间,它会丢失位置信息。 python包skimage带有一个segmentation模块,它提供了一些超像素分割方法。 quickshift 方法基于 meanshift 所基于的“模式搜索”机制。这些方法都不会分割出图像中的整个对象。它们提供了极其本地化的分割。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-08
        • 1970-01-01
        • 2014-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-08
        相关资源
        最近更新 更多