Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Kmeans、Opencv和Python进行颜色分割_Python_Opencv_Cluster Analysis_K Means_Image Segmentation - Fatal编程技术网

使用Kmeans、Opencv和Python进行颜色分割

使用Kmeans、Opencv和Python进行颜色分割,python,opencv,cluster-analysis,k-means,image-segmentation,Python,Opencv,Cluster Analysis,K Means,Image Segmentation,我有一个带有字母和不同颜色形状的图像。我需要对它们执行kmeans聚类,然后提供两个不同的图像,一个仅重新生成形状,另一个仅重新生成字母颜色。 这是一个原始图像样本,也是我需要实现的 同样的,另一个只有白色的R 我已经成功地执行了kmeans群集算法,如何访问标签和群集idx以重新生成所需的结果?有人能用一个示例代码来说明吗。这是代码。提前谢谢 import numpy as np import cv2 img = cv2.imread("/home/manohar/Outputs/Targ

我有一个带有字母和不同颜色形状的图像。我需要对它们执行kmeans聚类,然后提供两个不同的图像,一个仅重新生成形状,另一个仅重新生成字母颜色。 这是一个原始图像样本,也是我需要实现的

同样的,另一个只有白色的R

我已经成功地执行了kmeans群集算法,如何访问标签和群集idx以重新生成所需的结果?有人能用一个示例代码来说明吗。这是代码。提前谢谢

import numpy as np
import cv2

img = cv2.imread("/home/manohar/Outputs/Targets/m-0.PNG",1)
cv2.imshow("original",img)

Z = img.reshape((-1,3))

# convert to np.float32
Z = np.float32(Z)

# Here we are applying k-means clustering so that the pixels around a colour are consistent and gave same BGR/HSV values 


# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# We are going to cluster with k = 2, because the image will have just two colours ,a white background and the colour of the patch
K = 3
attempts=10
ret,label,center=cv2.kmeans(Z,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS)

# Now convert back into uint8
#now we have to access the labels to regenerate the clustered image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
#res2 is the result of the frame which has undergone k-means clustering


cv2.imshow("res2",res2)
cv2.waitKey()
cv2.destroyAllWindows()

好的,如果您想将所有被
K-Means
分类为“白色”的像素都改为黑色,那么您需要首先查看哪个标签对应于“白色”类别。您可以通过查看白色(
255255255
)所属的
center
(其中包含生成的k个中心)索引来实现这一点,如下所示:

white_index = 0
for b,g,r in center:
    #check if it is white
    if b == g == r == 255:
        #then this is the white category
        break
    white_index = white_index + 1
请注意,由于
k-means
是一种未经监督的方法,因此您的类别可能不一定完全是白色的(可能类似于
250249254
)。所以你应该在搜索索引时考虑这一点,即你应该寻找更接近白色的颜色。您可以通过应用公式比较颜色来实现这一点

然而,根据我的经验,我相信
center
已经以某种方式对结果中心进行了排序(更大的像素值往往首先出现),并且我注意到靠近白色的中心具有更低的索引(因此白色可能是索引0)。但最好是确认一下

现在您已经知道什么索引对应于白色,您可以看到哪些像素被分类到
标签中的
变量中。为此,有几种方法可以做到这一点,其中一种方法肯定比其他方法更有效:

#Copy image to modify it
img_copy = img[:]
#Reshape label to match the original image
new_label = label.reshape(img.shape)
#iterate over new_label, and if the category is white
#paint pixel corresponding to row,col black
row = 0
for i in new_label:
    column = 0
    for category in i:
        if category == white_index:
            #paint that pixel black
            img_copy[row,column] = [0, 0, 0]
        column = column + 1
    row = row + 1

#now show edited image
cv2.imshow("Object Removed",img_copy)
cv2.waitKey()
cv2.destroyAllWindows()
编辑:上述代码将获取一幅检测到的颜色已删除(变黑)的图像。为了获得其补码,即只有检测到的对象可见的图像,您可以执行以下几项操作。一种方法是获取
img
的副本,并将非该颜色的像素(无
category==white\u index
)变黑,如:


仅获取提取对象的另一种更复杂的方法是获取对象的形状(通过阈值化并使用
cv2.findContents()
),然后应用
cv2.boundingRect()
,以便可以使用对象获取较小的剪辑(通过使用给定矩形剪裁
img
)。您可以在详细解释的地方查看该链接

谢谢你的答复,先生,但这不是我想要达到的。当我传递任何带有形状和字母的图像时,我只想重新生成两个新图像,一个只有形状,另一个只有字母颜色。先生,我该怎么做?在C++中,我们使用CultStIdx,如何在Python中执行这个操作?你的问题还问了如何访问中心和标签。你能澄清一下你的意思吗?如果我理解正确,您希望图像中删除检测到的对象(如我在回答中已通过涂黑形状解释的图像)以及仅包含提取对象(字母)的图像?根据您的评论编辑我的答案您是否能够尝试我的解决方案,或者它是否有用?
#Obtain another copy of image to modify it
extract = img[:]
#Now do the opposite, iterate over new_label, and if the category is  Not white
#paint pixel corresponding to row,col black
row = 0
for i in new_label:
    column = 0
    for category in i:
        if category != white_index:
            #paint that pixel black
            extract[row,column] = [0, 0, 0]
        column = column + 1
    row = row + 1

#show or do whatever you want...