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
Python 在N个图像中分割图像,其中N是图像上出现的颜色数_Python_Opencv - Fatal编程技术网

Python 在N个图像中分割图像,其中N是图像上出现的颜色数

Python 在N个图像中分割图像,其中N是图像上出现的颜色数,python,opencv,Python,Opencv,我正在尝试根据图像包含的颜色分割图像 我之前的步骤是使用Sklearn提供的KMeans算法将其简化为3种颜色,结果如下图所示 现在我需要把它分成3张图片,每种颜色一张。并获得类似的东西(我已经用photoshop完成了) 这些例子都是黑白的,因为如果我能做除法,我就不再需要颜色了。但我会做同样的3色图像 掩码1: 面具2: 面具3: 我发现了这一点,但我无法实现我的目标 我曾考虑过通过渠道分开,但我认为这是错误的 # set green and red channels to 0 bl

我正在尝试根据图像包含的颜色分割图像

我之前的步骤是使用
Sklearn
提供的KMeans算法将其简化为3种颜色,结果如下图所示

现在我需要把它分成3张图片,每种颜色一张。并获得类似的东西(我已经用photoshop完成了)

这些例子都是黑白的,因为如果我能做除法,我就不再需要颜色了。但我会做同样的3色图像

掩码1:

面具2:

面具3:

我发现了这一点,但我无法实现我的目标

我曾考虑过通过渠道分开,但我认为这是错误的

# set green and red channels to 0
blue_img[:, :, 1] = 0
blue_img[:, :, 2] = 0
# set blue and red channels to 0
green_img[:, :, 0] = 0
green_img[:, :, 2] = 0
# set blue and green channels to 0
red_img[:, :, 0] = 0
red_img[:, :, 1] = 0
我认为关键在于我的kmeans算法,因为我用它获得了我的颜色的
标签
质心
,但我真的不知道怎么做,也找不到任何人这样做

我的KMeans算法是:

def get_colors(img, number_of_colors, show_chart, show_segmented_img):
    
    modified_image = img.reshape(img.shape[0]*img.shape[1], 3)
    
    myKMeans = KMeans(n_clusters = number_of_colors)
    
    labels = myKMeans.fit_predict(modified_image)
    
    counts = Counter(labels)
    
    centroids = myKMeans.cluster_centers_
    
    ordered_colors = [centroids[i] for i in counts.keys()]
    
    hex_colors = [RGB2HEX(ordered_colors[i]) for i in counts.keys()]
    
    rgb_colors = [ordered_colors[i] for i in counts.keys()]
    
    if (show_chart):
        plt.figure(figsize = (8, 6))
        plt.pie(counts.values(), labels = hex_colors, colors = hex_colors)
        plt.show()

    if (show_segmented_img):
        centroids = np.uint8(centroids)
        segmented_data = centroids[labels.flatten()]
        segmented_image = segmented_data.reshape(img.shape)
        segmented_image = cv2.cvtColor(segmented_image, cv2.COLOR_RGB2BGR)
        cv2.imwrite('segmentedImg.png', segmented_image)

    return hex_colors, rgb_colors
有人能帮我吗

多谢各位

编辑:来自小森的答案。

从Hihikomori的回答中,我明白我应该做以下工作,这是基于我之前链接的,但问题是我得到了3个没有任何轮廓的黑色面具,所以我认为这不适合我

def get_colors(img, number_of_colors, show_chart, show_segmented_img):
    
    modified_image = img.reshape(img.shape[0]*img.shape[1], 3)
    
    myKMeans = KMeans(n_clusters = number_of_colors)
    
    labels = myKMeans.fit_predict(modified_image)
    
    counts = Counter(labels)
    
    centroids = myKMeans.cluster_centers_
    
    ordered_colors = [centroids[i] for i in counts.keys()]
    
    hex_colors = [RGB2HEX(ordered_colors[i]) for i in counts.keys()]
    
    rgb_colors = [ordered_colors[i] for i in counts.keys()]

    # TRYING THE ASNWER
    color1, color2,color3 = rgb_colors
    first_color_indices = np.where(np.all(img == color1, axis=-1))
    second_color_indices = np.where(np.all(img == color2, axis=-1))
    third_color_indices = np.where(np.all(img == color3, axis=-1))

    img1 = np.zeros_like(img)
    img1[first_color_indices]=color1

    img2 = np.zeros_like(img)
    img2[second_color_indices]=color2

    img3 = np.zeros_like(img)
    img3[third_color_indices]=color3

    print('***')
    cv2_imshow(img1)
    print('***')
    cv2_imshow(img2)
    print('***')
    cv2_imshow(img3)
    print('***')
    
    if (show_chart):
        plt.figure(figsize = (8, 6))
        plt.pie(counts.values(), labels = hex_colors, colors = hex_colors)
        plt.show()

    if (show_segmented_img):
        centroids = np.uint8(centroids)
        segmented_data = centroids[labels.flatten()]
        segmented_image = segmented_data.reshape(img.shape)
        segmented_image = cv2.cvtColor(segmented_image, cv2.COLOR_RGB2BGR)
        cv2.imwrite('segmentedImg.png', segmented_image)

    return hex_colors, rgb_colors

您可以使用
np.unique()
在图像中找到唯一的颜色,然后对其进行迭代,将每个像素设置为白色或黑色,具体取决于它是否等于该颜色:

#!/usr/bin/env python3

import cv2
import numpy as np

# Load image
im = cv2.imread('cheese.png')

# Reshape into a tall column of pixels, each with 3 RGB pixels and get unique rows (colours)
colours  = np.unique(im.reshape(-1,3), axis=0)

# Iterate over the colours we found
for i,colour in enumerate(colours):
    print(f'DEBUG: colour {i}: {colour}')
    res = np.where((im==colour).all(axis=-1),255,0)
    cv2.imwrite(f'colour-{i}.png', res)
样本输出

DEBUG: colour 0: [0 0 0]
DEBUG: colour 1: [0 141 196]
DEBUG: colour 2: [1 102 133]


如果每个遮罩代表不同的颜色,为什么遮罩有一些相同的区域?因为我在使用photoshop制作示例时弄错了,对不起,您是否考虑过将图像转换为HLS或HSV矩阵?色调代表颜色,如红-绿-蓝
cv2.cvt颜色(图像,cv2.color\u BGR2HSV)
首先,谢谢!但我只有3个带这个密码的黑色面具。我已经编辑了我的问题,以防你看到错误(可能很傻)。
DEBUG: colour 0: [0 0 0]
DEBUG: colour 1: [0 141 196]
DEBUG: colour 2: [1 102 133]