Skip to content

Commit

Permalink
Find nearest color
Browse files Browse the repository at this point in the history
  • Loading branch information
mtouzot committed Feb 14, 2025
1 parent bee6444 commit 60e5d9a
Show file tree
Hide file tree
Showing 4 changed files with 363 additions and 5 deletions.
41 changes: 41 additions & 0 deletions gamebeye/gbcamcolors/color_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import numpy as np
import numpy.typing as npt
import skimage.color


def clamp(val: int) -> int:
Expand Down Expand Up @@ -336,3 +337,43 @@ def bgr_to_rgb(bgr_val: npt.ArrayLike) -> np.ndarray:
if not isinstance(bgr_val, tuple):
bgr_val = tuple(clamp_rgb(bgr_val))
return bgr_val[::-1]


def scaled_array(
array: list, src_range: list[int], dest_range: list[int]
) -> np.ndarray:
"""
Scale an array from a source range to a destination range.
:param list array: array to scale
:returns: a scaled array
:rtype: np.ndarray
>>> from gamebeye.gbcamcolors.color_helpers import scaled_array
>>> scaled_array([0, 0, 255], [0, 255], [0, 1])
np.array([0., 0., 1.])
>>> scaled_array([512, 128, 0], [0, 255], [0, 1])
array([2.00784314, 0.50196078, 0. ])
"""
array = np.array(array)
src_min, src_max = src_range
dest_min, dest_max = dest_range
return (array - src_min) / (src_max - src_min) * (dest_max - dest_min) + dest_min


def rgb_to_lab(rgb_val):
"""
Convert a (R, G, B) array to a (L, a, b) array.
:param list rgb_val: (R, G, B) list to convert
:returns: a list containing L, a, b values.
:rtype: np.array
>>> from gamebeye.gbcamcolors.color_helpers import rgb_to_lab
>>> rgb_to_lab([25, 50, 75])
array([ 20.0262693 , -0.6623394 , -18.32821659])
"""
rgb_val = scaled_array(rgb_val, [0, 255], [0, 1])
return skimage.color.rgb2lab(rgb_val)
27 changes: 25 additions & 2 deletions gamebeye/gbcamcolors/gbcolorvalues.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from enum import Enum, unique
from typing import List, Tuple

from gamebeye.gbcamcolors.color_helpers import hex_to_rgb
from skimage.color import deltaE_ciede2000

from gamebeye.gbcamcolors.color_helpers import hex_to_rgb, rgb_to_lab


# Class decorator @unique ensure each enum value is unique
Expand Down Expand Up @@ -2332,7 +2334,28 @@ def rgb_colors(self) -> List[int]:
:rtype: list[int]
>>> from gamebeye.gbcamcolors.gbcolorvalues import GBColorValues
>>> GBcolorValues.ROYAL_NAVY_BLUE
>>> GBColorValues.ROYAL_NAVY_BLUE
[1, 99, 198]
"""
return hex_to_rgb(self.value)

@classmethod
def nearest_color(cls, rgb_value):
"""
Find nearest color value among the GBColorValues.
:param list rgb_val: (R, G, B) list to convert
:return: the nearest color from the GBColorValues
:rtype: GBColorValue
>>> from gamebeye.gbcamcolors.gbcolorvalues import GBColorValues
>>> GBColorValues.nearest_color([2, 100, 198])
<GBColorValues.ROYAL_NAVY_BLUE: '#0163C6'>
"""
ref_lab_color = rgb_to_lab(rgb_value)
distance = []
for color in cls:
lab_color = rgb_to_lab(color.rgb_colors)
distance.append((color, deltaE_ciede2000(ref_lab_color, lab_color)))
return min(distance, key=lambda d: d[1])[0]
Loading

0 comments on commit 60e5d9a

Please sign in to comment.