Алгоритм среднего сдвига Scikit возвращает черную картинку
Я пытаюсь выполнить сегментацию изображения, используя алгоритм среднего смещения 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 ответа
Для отображения изображения правильный код будет
segmentedImg = cluster_centers[np.reshape(labels, originShape[:2])]
cv2.imshow('Image',segmentedImg.astype(np.uint8)
cv2.waitKey(0)
cv2.destroyAllWindows()
Я попробовал ваш метод сегментации на случайном образце фотографии, и сегментация выглядела плохо, вероятно, потому что, поскольку ваше среднее смещение работает только на цветовом пространстве, оно теряет информацию о местоположении. Пакет Python Skimage поставляется с модулем сегментации, и он предлагает несколько методов сегментации суперпикселей. Метод быстрой смены основан на механизме "поиска мод", на котором основано смещение. Ни один из этих методов не сегментирует весь объект на изображении. Они обеспечивают чрезвычайно локализованную сегментацию.
Вы можете преобразовать в другое цветовое пространство (например, Lab
цветовое пространство, используя следующий код) и сегментируйте цвета (отбрасывая интенсивность).
from skimage.color import rgb2lab
image = rgb2lab(image)
Затем используйте приведенный выше код для настройки параметров (quantile
а также n_samples
) функции estimate_bandwidth()
и, наконец, используйте matplotlib
с 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()
чтобы получить следующий результат с pepper
образ.
Проблема в том, что вы пытаетесь отобразить метки, вы должны использовать карту меток для преобразования изображения в суперпиксели.
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()