Python 中的相似颜色检测
Similar color detection in Python
给定一个 RGB 或 Hex 颜色,我如何找到与其相似的颜色?我所说的相似是指它们应该可以通过较小的值来区分。
RGB 颜色 space 取决于设备并且在感知上不统一。如果您打算测量颜色相似性,您应该首先将 RGB 值转换为与设备无关且感知上更均匀的颜色 space,例如 CIELAB. Then you can measure the color differences through a proper similarity metric, like Lab Delta E.
演示
考虑 this image:
假设您的参考颜色是绿色阴影和洋红色阴影,其 RGB 值例如为 [0, 160, 0]
和 [120, 0, 140]
。以下代码片段标识了那些相对于参考颜色的 Delta E 低于特定阈值(分别为 15
和 20
)的图像像素。
import numpy as np
from skimage import io
from skimage.color import rgb2lab, deltaE_cie76
rgb = io.imread('https://i.stack.imgur.com/npnrv.png')
lab = rgb2lab(rgb)
green = [0, 160, 0]
magenta = [120, 0, 140]
threshold_green = 15
threshold_magenta = 20
green_3d = np.uint8(np.asarray([[green]]))
magenta_3d = np.uint8(np.asarray([[magenta]]))
dE_green = deltaE_cie76(rgb2lab(green_3d), lab)
dE_magenta = deltaE_cie76(rgb2lab(magenta_3d), lab)
rgb[dE_green < threshold_green] = green_3d
rgb[dE_magenta < threshold_magenta] = magenta_3d
io.imshow(rgb)
基于 Tonechas 的回答,
要有相似的颜色检测值(而不是可视化):
import numpy as np
from skimage import io
from skimage.color import rgb2lab, deltaE_cie76
def get_pct_color(img_rgb, rgb_color, threshold=10):
img_lab = rgb2lab(img_rgb)
rgb_color_3d = np.uint8(np.asarray([[rgb_color]]))
rgb_color_lab = rgb2lab(rgb_color_3d)
delta = deltaE_cie76(rgb_color_lab, img_lab)
x_positions, y_positions = np.where(delta < threshold)
nb_pixel = img_rgb.shape[0] * img_rgb.shape[1]
pct_color = len(x_positions) / nb_pixel
return pct_color
举个例子:
img_rgb = io.imread('https://i.stack.imgur.com/npnrv.png')
green = [0, 160, 0]
get_pct_color(img_rgb, green, 10)
# 0.016131591796875
get_pct_color(img_rgb, green, 250)
# 1.0
给定一个 RGB 或 Hex 颜色,我如何找到与其相似的颜色?我所说的相似是指它们应该可以通过较小的值来区分。
RGB 颜色 space 取决于设备并且在感知上不统一。如果您打算测量颜色相似性,您应该首先将 RGB 值转换为与设备无关且感知上更均匀的颜色 space,例如 CIELAB. Then you can measure the color differences through a proper similarity metric, like Lab Delta E.
演示
考虑 this image:
假设您的参考颜色是绿色阴影和洋红色阴影,其 RGB 值例如为 [0, 160, 0]
和 [120, 0, 140]
。以下代码片段标识了那些相对于参考颜色的 Delta E 低于特定阈值(分别为 15
和 20
)的图像像素。
import numpy as np
from skimage import io
from skimage.color import rgb2lab, deltaE_cie76
rgb = io.imread('https://i.stack.imgur.com/npnrv.png')
lab = rgb2lab(rgb)
green = [0, 160, 0]
magenta = [120, 0, 140]
threshold_green = 15
threshold_magenta = 20
green_3d = np.uint8(np.asarray([[green]]))
magenta_3d = np.uint8(np.asarray([[magenta]]))
dE_green = deltaE_cie76(rgb2lab(green_3d), lab)
dE_magenta = deltaE_cie76(rgb2lab(magenta_3d), lab)
rgb[dE_green < threshold_green] = green_3d
rgb[dE_magenta < threshold_magenta] = magenta_3d
io.imshow(rgb)
基于 Tonechas 的回答,
要有相似的颜色检测值(而不是可视化):
import numpy as np
from skimage import io
from skimage.color import rgb2lab, deltaE_cie76
def get_pct_color(img_rgb, rgb_color, threshold=10):
img_lab = rgb2lab(img_rgb)
rgb_color_3d = np.uint8(np.asarray([[rgb_color]]))
rgb_color_lab = rgb2lab(rgb_color_3d)
delta = deltaE_cie76(rgb_color_lab, img_lab)
x_positions, y_positions = np.where(delta < threshold)
nb_pixel = img_rgb.shape[0] * img_rgb.shape[1]
pct_color = len(x_positions) / nb_pixel
return pct_color
举个例子:
img_rgb = io.imread('https://i.stack.imgur.com/npnrv.png')
green = [0, 160, 0]
get_pct_color(img_rgb, green, 10)
# 0.016131591796875
get_pct_color(img_rgb, green, 250)
# 1.0