mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	Remove matplotlib and generate color palette to mimic matplotlib's colors (#12327)
This commit is contained in:
		
							parent
							
								
									188a7de467
								
							
						
					
					
						commit
						a0741aa7b1
					
				@ -4,7 +4,6 @@ Flask_Limiter == 3.7.*
 | 
			
		||||
imutils == 0.5.*
 | 
			
		||||
joserfc == 0.11.*
 | 
			
		||||
markupsafe == 2.1.*
 | 
			
		||||
matplotlib == 3.8.*
 | 
			
		||||
mypy == 1.6.1
 | 
			
		||||
numpy == 1.26.*
 | 
			
		||||
onvif_zeep == 0.2.12
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,6 @@ from enum import Enum
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
from typing import Any, Dict, List, Optional, Tuple, Union
 | 
			
		||||
 | 
			
		||||
import matplotlib.pyplot as plt
 | 
			
		||||
import numpy as np
 | 
			
		||||
from pydantic import (
 | 
			
		||||
    BaseModel,
 | 
			
		||||
@ -43,6 +42,7 @@ from frigate.plus import PlusApi
 | 
			
		||||
from frigate.util.builtin import (
 | 
			
		||||
    deep_merge,
 | 
			
		||||
    escape_special_characters,
 | 
			
		||||
    generate_color_palette,
 | 
			
		||||
    get_ffmpeg_arg_list,
 | 
			
		||||
    load_config_with_no_duplicates,
 | 
			
		||||
)
 | 
			
		||||
@ -1033,10 +1033,11 @@ class CameraConfig(FrigateBaseModel):
 | 
			
		||||
    def __init__(self, **config):
 | 
			
		||||
        # Set zone colors
 | 
			
		||||
        if "zones" in config:
 | 
			
		||||
            colors = plt.cm.get_cmap("tab10", len(config["zones"]))
 | 
			
		||||
            colors = generate_color_palette(len(config["zones"]))
 | 
			
		||||
 | 
			
		||||
            config["zones"] = {
 | 
			
		||||
                name: {**z, "color": tuple(round(255 * c) for c in colors(idx)[:3])}
 | 
			
		||||
                for idx, (name, z) in enumerate(config["zones"].items())
 | 
			
		||||
                name: {**z, "color": color}
 | 
			
		||||
                for (name, z), color in zip(config["zones"].items(), colors)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        # add roles to the input if there is only one
 | 
			
		||||
 | 
			
		||||
@ -5,13 +5,12 @@ import os
 | 
			
		||||
from enum import Enum
 | 
			
		||||
from typing import Dict, Optional, Tuple
 | 
			
		||||
 | 
			
		||||
import matplotlib.pyplot as plt
 | 
			
		||||
import requests
 | 
			
		||||
from pydantic import BaseModel, ConfigDict, Field
 | 
			
		||||
from pydantic.fields import PrivateAttr
 | 
			
		||||
 | 
			
		||||
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__)
 | 
			
		||||
 | 
			
		||||
@ -128,10 +127,9 @@ class ModelConfig(BaseModel):
 | 
			
		||||
 | 
			
		||||
    def create_colormap(self, enabled_labels: set[str]) -> None:
 | 
			
		||||
        """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[val] = tuple(int(round(255 * c)) for c in cmap(key)[:3])
 | 
			
		||||
        self._colormap = {label: color for label, color in zip(enabled_labels, colors)}
 | 
			
		||||
 | 
			
		||||
    model_config = ConfigDict(extra="forbid", protected_namespaces=())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -349,3 +349,39 @@ def empty_and_close_queue(q: mp.Queue):
 | 
			
		||||
            q.close()
 | 
			
		||||
            q.join_thread()
 | 
			
		||||
            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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user