如何使用直方图找到主色 RGB?
How to find dominant color RGB using histograms?
我目前正在开发一系列测试代码来探索处理图像数据的不同方式,我的主要课题之一是颜色提取。
我开发了以下 Python 代码,给定一张图像,它能够提取其对应的具有 R、G 和 B 值的直方图:
# Reading original image, in full color
img = mpimg.imread('/content/brandlogos/Images/14 (48).jpg')
# Displaying the image
imgplot = plt.imshow(img)
plt.show()
# Creating a tuple to select colors of each channel line
colors = ("r", "g", "b")
channel_ids = (0, 1, 2)
# Making an histogram with three lines, one for each color
# The X limit is 255, for RGB values
plt.xlim([0,256])
for channel_id, c in zip(channel_ids, colors):
histogram, bin_edges = np.histogram(
img[:, :, channel_id], bins = 256, range=(0,256)
)
plt.plot(bin_edges[0:-1], histogram, color=c )
# Displaying the histogram
plt.xlabel("Color Value")
plt.ylabel("Pixels")
plt.show()
示例:
但是,我现在想根据直方图信息,找到最主要颜色的RGB值。
预期输出:(87, 74, 163)
(或类似的东西)
我将如何找到三个颜色通道的最高 bin 计数,并将它们组合成一种颜色?
您可以关注图像中的 unique
种颜色,并找到计数最高的颜色:
import matplotlib.image as mpimg
import numpy as np
img = np.uint8(mpimg.imread('path/to/your/image.png') * 255)
img = np.reshape(img, (np.prod(img.shape[:2]), 3))
res = np.unique(img, axis=0, return_counts=True)
dom_color = res[0][np.argmax(res[1]), :]
print(dom_color)
或者,您可以使用 Pillow 的 getcolors
,并获得计数最高的那个:
from PIL import Image
img = Image.open('path/to/your/image.png')
dom_color = sorted(img.getcolors(2 ** 24), reverse=True)[0][1]
print(dom_color)
如果需要,两者还可以轻松提供第二、第三……主色。
对于这样的徽标
主色为:
[208 16 18]
分别
(208, 16, 18)
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
PyCharm: 2021.1.1
Matplotlib: 3.4.1
NumPy: 1.20.2
Pillow: 8.2.0
----------------------------------------
编辑: 也许,为了给直方图方法一个对手,正如 Cris 在评论中所解释的那样,请看这张图片:
很难看出来,但是有三种不同类型的红色,最大的矩形的 RGB 值为 (208, 0, 18)
。
现在,让我们将您的直方图方法与 Pillow 的 getcolors
:
进行比较
import numpy as np
from PIL import Image
adv = np.zeros((512, 512, 3), np.uint8)
adv[:200, :200, :] = [208, 16, 18]
adv[:200, 200:, :] = [208, 16, 0]
adv[200:, :200, :] = [0, 16, 18]
adv[200:, 200:, :] = [208, 0, 18]
# Histogram approach
dom_color = []
for channel_id in [0, 1, 2]:
dom_color.append(np.argmax(np.histogram(adv[..., channel_id], bins=256, range=(0, 256))[0]))
print(dom_color)
# [208, 16, 18]
# Pillow's getcolors
dom_color = sorted(Image.fromarray(adv).getcolors(2 ** 24), reverse=True)[0][1]
print(dom_color)
# (208, 0, 18)
对手正在建立以在 (208, 16, 18)
处给出直方图峰值。然而,主色是(208, 0, 18)
,因为我们可以很容易地从图像(或代码)中得出。
我目前正在开发一系列测试代码来探索处理图像数据的不同方式,我的主要课题之一是颜色提取。
我开发了以下 Python 代码,给定一张图像,它能够提取其对应的具有 R、G 和 B 值的直方图:
# Reading original image, in full color
img = mpimg.imread('/content/brandlogos/Images/14 (48).jpg')
# Displaying the image
imgplot = plt.imshow(img)
plt.show()
# Creating a tuple to select colors of each channel line
colors = ("r", "g", "b")
channel_ids = (0, 1, 2)
# Making an histogram with three lines, one for each color
# The X limit is 255, for RGB values
plt.xlim([0,256])
for channel_id, c in zip(channel_ids, colors):
histogram, bin_edges = np.histogram(
img[:, :, channel_id], bins = 256, range=(0,256)
)
plt.plot(bin_edges[0:-1], histogram, color=c )
# Displaying the histogram
plt.xlabel("Color Value")
plt.ylabel("Pixels")
plt.show()
示例:
但是,我现在想根据直方图信息,找到最主要颜色的RGB值。
预期输出:(87, 74, 163)
(或类似的东西)
我将如何找到三个颜色通道的最高 bin 计数,并将它们组合成一种颜色?
您可以关注图像中的 unique
种颜色,并找到计数最高的颜色:
import matplotlib.image as mpimg
import numpy as np
img = np.uint8(mpimg.imread('path/to/your/image.png') * 255)
img = np.reshape(img, (np.prod(img.shape[:2]), 3))
res = np.unique(img, axis=0, return_counts=True)
dom_color = res[0][np.argmax(res[1]), :]
print(dom_color)
或者,您可以使用 Pillow 的 getcolors
,并获得计数最高的那个:
from PIL import Image
img = Image.open('path/to/your/image.png')
dom_color = sorted(img.getcolors(2 ** 24), reverse=True)[0][1]
print(dom_color)
如果需要,两者还可以轻松提供第二、第三……主色。
对于这样的徽标
主色为:
[208 16 18]
分别
(208, 16, 18)
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
PyCharm: 2021.1.1
Matplotlib: 3.4.1
NumPy: 1.20.2
Pillow: 8.2.0
----------------------------------------
编辑: 也许,为了给直方图方法一个对手,正如 Cris 在评论中所解释的那样,请看这张图片:
很难看出来,但是有三种不同类型的红色,最大的矩形的 RGB 值为 (208, 0, 18)
。
现在,让我们将您的直方图方法与 Pillow 的 getcolors
:
import numpy as np
from PIL import Image
adv = np.zeros((512, 512, 3), np.uint8)
adv[:200, :200, :] = [208, 16, 18]
adv[:200, 200:, :] = [208, 16, 0]
adv[200:, :200, :] = [0, 16, 18]
adv[200:, 200:, :] = [208, 0, 18]
# Histogram approach
dom_color = []
for channel_id in [0, 1, 2]:
dom_color.append(np.argmax(np.histogram(adv[..., channel_id], bins=256, range=(0, 256))[0]))
print(dom_color)
# [208, 16, 18]
# Pillow's getcolors
dom_color = sorted(Image.fromarray(adv).getcolors(2 ** 24), reverse=True)[0][1]
print(dom_color)
# (208, 0, 18)
对手正在建立以在 (208, 16, 18)
处给出直方图峰值。然而,主色是(208, 0, 18)
,因为我们可以很容易地从图像(或代码)中得出。