Remove matplotlib and generate color palette to mimic matplotlib's colors (#12327)

This commit is contained in:
Josh Hawkins 2024-07-07 13:53:00 -05:00 committed by GitHub
parent 188a7de467
commit a0741aa7b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 10 deletions

View File

@ -4,7 +4,6 @@ Flask_Limiter == 3.7.*
imutils == 0.5.* imutils == 0.5.*
joserfc == 0.11.* joserfc == 0.11.*
markupsafe == 2.1.* markupsafe == 2.1.*
matplotlib == 3.8.*
mypy == 1.6.1 mypy == 1.6.1
numpy == 1.26.* numpy == 1.26.*
onvif_zeep == 0.2.12 onvif_zeep == 0.2.12

View File

@ -7,7 +7,6 @@ from enum import Enum
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple, Union from typing import Any, Dict, List, Optional, Tuple, Union
import matplotlib.pyplot as plt
import numpy as np import numpy as np
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@ -43,6 +42,7 @@ from frigate.plus import PlusApi
from frigate.util.builtin import ( from frigate.util.builtin import (
deep_merge, deep_merge,
escape_special_characters, escape_special_characters,
generate_color_palette,
get_ffmpeg_arg_list, get_ffmpeg_arg_list,
load_config_with_no_duplicates, load_config_with_no_duplicates,
) )
@ -1033,10 +1033,11 @@ class CameraConfig(FrigateBaseModel):
def __init__(self, **config): def __init__(self, **config):
# Set zone colors # Set zone colors
if "zones" in config: if "zones" in config:
colors = plt.cm.get_cmap("tab10", len(config["zones"])) colors = generate_color_palette(len(config["zones"]))
config["zones"] = { config["zones"] = {
name: {**z, "color": tuple(round(255 * c) for c in colors(idx)[:3])} name: {**z, "color": color}
for idx, (name, z) in enumerate(config["zones"].items()) for (name, z), color in zip(config["zones"].items(), colors)
} }
# add roles to the input if there is only one # add roles to the input if there is only one

View File

@ -5,13 +5,12 @@ import os
from enum import Enum from enum import Enum
from typing import Dict, Optional, Tuple from typing import Dict, Optional, Tuple
import matplotlib.pyplot as plt
import requests import requests
from pydantic import BaseModel, ConfigDict, Field from pydantic import BaseModel, ConfigDict, Field
from pydantic.fields import PrivateAttr from pydantic.fields import PrivateAttr
from frigate.plus import PlusApi from frigate.plus import PlusApi
from frigate.util.builtin import load_labels from frigate.util.builtin import generate_color_palette, load_labels
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -128,10 +127,9 @@ class ModelConfig(BaseModel):
def create_colormap(self, enabled_labels: set[str]) -> None: def create_colormap(self, enabled_labels: set[str]) -> None:
"""Get a list of colors for enabled labels.""" """Get a list of colors for enabled labels."""
cmap = plt.cm.get_cmap("tab10", len(enabled_labels)) colors = generate_color_palette(len(enabled_labels))
for key, val in enumerate(enabled_labels): self._colormap = {label: color for label, color in zip(enabled_labels, colors)}
self._colormap[val] = tuple(int(round(255 * c)) for c in cmap(key)[:3])
model_config = ConfigDict(extra="forbid", protected_namespaces=()) model_config = ConfigDict(extra="forbid", protected_namespaces=())

View File

@ -349,3 +349,39 @@ def empty_and_close_queue(q: mp.Queue):
q.close() q.close()
q.join_thread() q.join_thread()
return return
def generate_color_palette(n):
# mimic matplotlib's color scheme
base_colors = [
(31, 119, 180), # blue
(255, 127, 14), # orange
(44, 160, 44), # green
(214, 39, 40), # red
(148, 103, 189), # purple
(140, 86, 75), # brown
(227, 119, 194), # pink
(127, 127, 127), # gray
(188, 189, 34), # olive
(23, 190, 207), # cyan
]
def interpolate(color1, color2, factor):
return tuple(int(c1 + (c2 - c1) * factor) for c1, c2 in zip(color1, color2))
if n <= len(base_colors):
return base_colors[:n]
colors = base_colors.copy()
step = 1 / (n - len(base_colors) + 1)
extra_colors_needed = n - len(base_colors)
# interpolate between the base colors to generate more if needed
for i in range(extra_colors_needed):
index = i % (len(base_colors) - 1)
factor = (i + 1) * step
color1 = base_colors[index]
color2 = base_colors[index + 1]
colors.append(interpolate(color1, color2, factor))
return colors