简体   繁体   English

在 N 个图像中分割图像,其中 N 是出现在其上的 colors 的数量

[英]Split image in N images, where N is the number of colors appearing on it

I'm trying to split an image depending on the colors it contains.我正在尝试根据它包含的 colors 拆分图像。

My previous steps have been to simplify it to just 3 colors using the KMeans algorithm that Sklearn offers and I get a result like the following image.我之前的步骤是使用Sklearn提供的 KMeans 算法将其简化为 3 colors,我得到如下图所示的结果。

在此处输入图像描述

Now I need to split it in 3 images one for each color.现在我需要将它分成 3 张图像,每种颜色一张。 And obtain something similar to this (I have done it with photoshop).并获得与此类似的东西(我已经用 Photoshop 完成了)。

The examples are done in black and white because really if I can do the division, I no longer need the colors.这些例子都是黑白的,因为如果我真的能做除法,我就不再需要 colors。 But I would do just as well with 3 color images.但我也可以使用 3 张彩色图像。

Mask 1:面具 1:

在此处输入图像描述

Mask 2:面具 2:

在此处输入图像描述

Mask 3:面具 3:

在此处输入图像描述

I found this question , but I can't achieve my goal.我找到了这个问题,但我无法实现我的目标。

I have thought about separating by channels, but I think it is wrong.我曾想过按渠道分开,但我认为这是错误的。

# 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

I think the key is in my kmeans algorithm, because with it I obtain labels and centroids of my colors but I really don't know how to do it, and I can't find anybody doing it.我认为关键在于我的 kmeans 算法,因为通过它我获得了 colors 的labelscentroids ,但我真的不知道该怎么做,而且我找不到任何人这样做。

My KMeans algorithm is:我的 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

can somebdoy help me please?有人可以帮帮我吗?

Thank you very much!非常感谢!

EDIT: From Hihikomori's answer.编辑:来自 Hihikomori 的回答。

From Hihikomori's answer, I understand that I should do the following, this is based on the question that I linked before, but the problem is that I get 3 black masks without any contour so I thought that this would not suit me.从 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

You can find the unique colours in your image with np.unique() and then iterate over them setting each pixel to either white or black depending whether it is equal to that colour or not:您可以使用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)

Sample Output样品 Output

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

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

color1 = (0,0,160)
color2 = (0,160,160)
color3 = (160,160,160)
img = np.zeros((640,480,3),np.uint8)

img[100:200,100:200] = color1
img[150:250,150:250] = color2
img[200:300,200:300] = color3

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

cv2.imshow('origin', img)
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey(0)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM