使用 k-means 进行图像分割
Image segmentation using k-means
我正在尝试将 k-means 算法用于图像分割任务。问题是我的程序没有分割图像。
你能帮我找出代码中的错误吗?
事实上,我已经将簇数固定为32。
我使用了以下数据结构:
3 个数组 bleu,vert,rouge 来存储每个像素的 RGB 值
3 个数组 cluster_bleu,cluster_rouge,cluster_vert 来存储每个簇的 RGB 值
groupe[i,0]=k 将每个像素 i 映射到簇 k
import cv2
import numpy
import random
def main():
MAX_LARGEUR = 400
MAX_HAUTEUR = 400
K = 32 #Le fameux parametre K de l'algorithme
imagecolor = cv2.imread('perr.jpg')
if imagecolor.shape[0] > MAX_LARGEUR or imagecolor.shape[1] > MAX_HAUTEUR:
factor1 = float(MAX_LARGEUR) / imagecolor.shape[0]
factor2 = float(MAX_HAUTEUR) / imagecolor.shape[1]
factor = min(factor1, factor2)
imagecolor = cv2.resize(imagecolor, None, fx=factor, fy=factor, interpolation=cv2.INTER_AREA)
nb_pixels = imagecolor.shape[0] * imagecolor.shape[1]
bleu = imagecolor[:, :, 0].reshape(nb_pixels, 1)
vert = imagecolor[:, :, 1].reshape(nb_pixels, 1)
rouge = imagecolor[:, :, 2].reshape(nb_pixels, 1)
cluster_bleu = numpy.zeros(K)
cluster_vert = numpy.zeros(K)
cluster_rouge = numpy.zeros(K)
groupe = numpy.zeros((nb_pixels, 1))
for i in range(0,K):
groupe[i,0]=i
for i in range(K,nb_pixels):
groupe[i,0]=random.randint(0, K-1)
condition =False
def etape1(indices,i):
s=indices.size
rouge_s=0
vert_s=0
bleu_s=0
#calcul de barycentre des points
if s==0:
cluster_rouge[i]=0
cluster_vert[i]=0
cluster_bleu[i]=0
if s >=1:
for j in range(0,s):
rouge_s=rouge_s+rouge[indices[j]]
vert_s=vert_s+vert[indices[j]]
bleu_s=bleu_s+bleu[indices[j]]
#mise jour des clusters
cluster_rouge[i]=rouge_s/s
cluster_vert[i]=vert_s/s
cluster_bleu[i]=bleu_s/s
iteration=0
oldGroupe = numpy.copy(groupe)
while(condition==False) :
for i in range(0,K):
indices=numpy.where(groupe==i)[0]
etape1(indices,i)
for i in range(0,nb_pixels):
minimum=10000;
dist=0;
index=-1;
for j in range(0,K):
dist=(cluster_rouge[j]-rouge[i])**2+(cluster_vert[j]-vert[i])**2+(cluster_bleu[j]-bleu[i])**2;
if(dist<=minimum):
minimum=dist;
index=j;
groupe[i,0]=index;
condition=numpy.all(groupe==oldGroupe)
oldGroupe = numpy.copy(groupe)
groupe=numpy.reshape(groupe, (imagecolor.shape[0], imagecolor.shape[1]))
for i in range(0, imagecolor.shape[0]):
for j in range(0, imagecolor.shape[1]):
imagecolor[i,j,0] = (cluster_bleu[groupe[i,j]])
imagecolor[i,j,1] = (cluster_vert[groupe[i,j]])
imagecolor[i,j,2] = (cluster_rouge[groupe[i,j]])
cv2.namedWindow("sortie")
cv2.imshow("sortie", imagecolor)
key = cv2.waitKey(0)
if __name__ == "__main__":
main()
问题是赋值 oldGroupe=groupe;
不复制数组,而是创建具有不同名称 (oldGroupe
) 的引用,指向与 groupe
相同的数据。因此,当您更改 groupe
时,您也会更改 oldGroupe
,并且 condition
始终为 True。
您想要的是用 oldGroupe = numpy.copy(groupe)
.
在 groupe
中创建数据副本
我正在尝试将 k-means 算法用于图像分割任务。问题是我的程序没有分割图像。 你能帮我找出代码中的错误吗?
事实上,我已经将簇数固定为32。 我使用了以下数据结构:
3 个数组 bleu,vert,rouge 来存储每个像素的 RGB 值
3 个数组 cluster_bleu,cluster_rouge,cluster_vert 来存储每个簇的 RGB 值
groupe[i,0]=k 将每个像素 i 映射到簇 k
import cv2 import numpy import random def main(): MAX_LARGEUR = 400 MAX_HAUTEUR = 400 K = 32 #Le fameux parametre K de l'algorithme imagecolor = cv2.imread('perr.jpg') if imagecolor.shape[0] > MAX_LARGEUR or imagecolor.shape[1] > MAX_HAUTEUR: factor1 = float(MAX_LARGEUR) / imagecolor.shape[0] factor2 = float(MAX_HAUTEUR) / imagecolor.shape[1] factor = min(factor1, factor2) imagecolor = cv2.resize(imagecolor, None, fx=factor, fy=factor, interpolation=cv2.INTER_AREA) nb_pixels = imagecolor.shape[0] * imagecolor.shape[1] bleu = imagecolor[:, :, 0].reshape(nb_pixels, 1) vert = imagecolor[:, :, 1].reshape(nb_pixels, 1) rouge = imagecolor[:, :, 2].reshape(nb_pixels, 1) cluster_bleu = numpy.zeros(K) cluster_vert = numpy.zeros(K) cluster_rouge = numpy.zeros(K) groupe = numpy.zeros((nb_pixels, 1)) for i in range(0,K): groupe[i,0]=i for i in range(K,nb_pixels): groupe[i,0]=random.randint(0, K-1) condition =False def etape1(indices,i): s=indices.size rouge_s=0 vert_s=0 bleu_s=0 #calcul de barycentre des points if s==0: cluster_rouge[i]=0 cluster_vert[i]=0 cluster_bleu[i]=0 if s >=1: for j in range(0,s): rouge_s=rouge_s+rouge[indices[j]] vert_s=vert_s+vert[indices[j]] bleu_s=bleu_s+bleu[indices[j]] #mise jour des clusters cluster_rouge[i]=rouge_s/s cluster_vert[i]=vert_s/s cluster_bleu[i]=bleu_s/s iteration=0 oldGroupe = numpy.copy(groupe) while(condition==False) : for i in range(0,K): indices=numpy.where(groupe==i)[0] etape1(indices,i) for i in range(0,nb_pixels): minimum=10000; dist=0; index=-1; for j in range(0,K): dist=(cluster_rouge[j]-rouge[i])**2+(cluster_vert[j]-vert[i])**2+(cluster_bleu[j]-bleu[i])**2; if(dist<=minimum): minimum=dist; index=j; groupe[i,0]=index; condition=numpy.all(groupe==oldGroupe) oldGroupe = numpy.copy(groupe) groupe=numpy.reshape(groupe, (imagecolor.shape[0], imagecolor.shape[1])) for i in range(0, imagecolor.shape[0]): for j in range(0, imagecolor.shape[1]): imagecolor[i,j,0] = (cluster_bleu[groupe[i,j]]) imagecolor[i,j,1] = (cluster_vert[groupe[i,j]]) imagecolor[i,j,2] = (cluster_rouge[groupe[i,j]]) cv2.namedWindow("sortie") cv2.imshow("sortie", imagecolor) key = cv2.waitKey(0) if __name__ == "__main__": main()
问题是赋值 oldGroupe=groupe;
不复制数组,而是创建具有不同名称 (oldGroupe
) 的引用,指向与 groupe
相同的数据。因此,当您更改 groupe
时,您也会更改 oldGroupe
,并且 condition
始终为 True。
您想要的是用 oldGroupe = numpy.copy(groupe)
.
groupe
中创建数据副本