【问题标题】:Split image in N images, where N is the number of colors appearing on it将图像拆分为 N 个图像,其中 N 是其上出现的颜色数
【发布时间】:2021-03-30 18:10:16
【问题描述】:

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

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

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

这些例子都是黑白的,因为如果我能做除法,我就不再需要颜色了。但我也可以使用 3 张彩色图像。

掩码 1:

面具 2:

面具 3:

我找到了这个question,但我无法实现我的目标。

我曾想过按渠道分开,但我认为这是错误的。

# 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 算法,因为有了它,我获得了我的颜色的labelscentroids,但我真的不知道该怎么做,而且我找不到任何人这样做。

我的 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 的回答。

从 Hihikomori 的回答中,我知道我应该执行以下操作,这是基于我之前链接的 question,但问题是我得到了 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

【问题讨论】:

  • 如果每个蒙版代表不同的颜色,为什么蒙版有一些共同的区域?
  • 因为我用photoshop做例子的时候弄错了,抱歉
  • 您是否考虑过将图像转换为 HLS 或 HSV 矩阵? Hue 代表颜色,如红绿蓝cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

标签: python opencv


【解决方案1】:

您可以使用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]

【讨论】:

    【解决方案2】:
    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)
    

    【讨论】:

    • 首先,谢谢!但我只用这段代码得到 3 个黑色面具。我已经编辑了我的问题,以防你看到错误(可能很傻)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2011-08-03
    • 2018-04-27
    • 2012-06-07
    • 1970-01-01
    相关资源
    最近更新 更多