defdraw_line(scene:np.ndarray,start:Point,end:Point,color:Color=Color.ROBOFLOW,thickness:int=2,)->np.ndarray:""" Draws a line on a given scene. Parameters: scene (np.ndarray): The scene on which the line will be drawn start (Point): The starting point of the line end (Point): The end point of the line color (Color): The color of the line, defaults to Color.ROBOFLOW thickness (int): The thickness of the line Returns: np.ndarray: The scene with the line drawn on it """cv2.line(scene,start.as_xy_int_tuple(),end.as_xy_int_tuple(),color.as_bgr(),thickness=thickness,)returnscene
defdraw_rectangle(scene:np.ndarray,rect:Rect,color:Color=Color.ROBOFLOW,thickness:int=2)->np.ndarray:""" Draws a rectangle on an image. Parameters: scene (np.ndarray): The scene on which the rectangle will be drawn rect (Rect): The rectangle to be drawn color (Color): The color of the rectangle thickness (int): The thickness of the rectangle border Returns: np.ndarray: The scene with the rectangle drawn on it """cv2.rectangle(scene,rect.top_left.as_xy_int_tuple(),rect.bottom_right.as_xy_int_tuple(),color.as_bgr(),thickness=thickness,)returnscene
defdraw_filled_rectangle(scene:np.ndarray,rect:Rect,color:Color=Color.ROBOFLOW,opacity:float=1)->np.ndarray:""" Draws a filled rectangle on an image. Parameters: scene (np.ndarray): The scene on which the rectangle will be drawn rect (Rect): The rectangle to be drawn color (Color): The color of the rectangle opacity (float): The opacity of rectangle when drawn on the scene. Returns: np.ndarray: The scene with the rectangle drawn on it """ifopacity==1:cv2.rectangle(scene,rect.top_left.as_xy_int_tuple(),rect.bottom_right.as_xy_int_tuple(),color.as_bgr(),-1,)else:scene_with_annotations=scene.copy()cv2.rectangle(scene_with_annotations,rect.top_left.as_xy_int_tuple(),rect.bottom_right.as_xy_int_tuple(),color.as_bgr(),-1,)cv2.addWeighted(scene_with_annotations,opacity,scene,1-opacity,gamma=0,dst=scene)returnscene
defdraw_polygon(scene:np.ndarray,polygon:np.ndarray,color:Color=Color.ROBOFLOW,thickness:int=2,)->np.ndarray:"""Draw a polygon on a scene. Parameters: scene (np.ndarray): The scene to draw the polygon on. polygon (np.ndarray): The polygon to be drawn, given as a list of vertices. color (Color): The color of the polygon. Defaults to Color.ROBOFLOW. thickness (int): The thickness of the polygon lines, by default 2. Returns: np.ndarray: The scene with the polygon drawn on it. """cv2.polylines(scene,[polygon],isClosed=True,color=color.as_bgr(),thickness=thickness)returnscene
defdraw_filled_polygon(scene:np.ndarray,polygon:np.ndarray,color:Color=Color.ROBOFLOW,opacity:float=1,)->np.ndarray:"""Draw a filled polygon on a scene. Parameters: scene (np.ndarray): The scene to draw the polygon on. polygon (np.ndarray): The polygon to be drawn, given as a list of vertices. color (Color): The color of the polygon. Defaults to Color.ROBOFLOW. opacity (float): The opacity of polygon when drawn on the scene. Returns: np.ndarray: The scene with the polygon drawn on it. """ifopacity==1:cv2.fillPoly(scene,[polygon],color=color.as_bgr())else:scene_with_annotations=scene.copy()cv2.fillPoly(scene_with_annotations,[polygon],color=color.as_bgr())cv2.addWeighted(scene_with_annotations,opacity,scene,1-opacity,gamma=0,dst=scene)returnscene
defdraw_text(scene:np.ndarray,text:str,text_anchor:Point,text_color:Color=Color.BLACK,text_scale:float=0.5,text_thickness:int=1,text_padding:int=10,text_font:int=cv2.FONT_HERSHEY_SIMPLEX,background_color:Optional[Color]=None,)->np.ndarray:""" Draw text with background on a scene. Parameters: scene (np.ndarray): A 2-dimensional numpy ndarray representing an image or scene text (str): The text to be drawn. text_anchor (Point): The anchor point for the text, represented as a Point object with x and y attributes. text_color (Color): The color of the text. Defaults to black. text_scale (float): The scale of the text. Defaults to 0.5. text_thickness (int): The thickness of the text. Defaults to 1. text_padding (int): The amount of padding to add around the text when drawing a rectangle in the background. Defaults to 10. text_font (int): The font to use for the text. Defaults to cv2.FONT_HERSHEY_SIMPLEX. background_color (Optional[Color]): The color of the background rectangle, if one is to be drawn. Defaults to None. Returns: np.ndarray: The input scene with the text drawn on it. Examples: ```python import numpy as np scene = np.zeros((100, 100, 3), dtype=np.uint8) text_anchor = Point(x=50, y=50) scene = draw_text(scene=scene, text="Hello, world!",text_anchor=text_anchor) ``` """text_width,text_height=cv2.getTextSize(text=text,fontFace=text_font,fontScale=text_scale,thickness=text_thickness,)[0]text_anchor_x,text_anchor_y=text_anchor.as_xy_int_tuple()text_rect=Rect(x=text_anchor_x-text_width//2,y=text_anchor_y-text_height//2,width=text_width,height=text_height,).pad(text_padding)ifbackground_colorisnotNone:scene=draw_filled_rectangle(scene=scene,rect=text_rect,color=background_color)cv2.putText(img=scene,text=text,org=(text_anchor_x-text_width//2,text_anchor_y+text_height//2),fontFace=text_font,fontScale=text_scale,color=text_color.as_bgr(),thickness=text_thickness,lineType=cv2.LINE_AA,)returnscene
defdraw_image(scene:np.ndarray,image:Union[str,np.ndarray],opacity:float,rect:Rect)->np.ndarray:""" Draws an image onto a given scene with specified opacity and dimensions. Args: scene (np.ndarray): Background image where the new image will be drawn. image (Union[str, np.ndarray]): Image to draw. opacity (float): Opacity of the image to be drawn. rect (Rect): Rectangle specifying where to draw the image. Returns: np.ndarray: The updated scene. Raises: FileNotFoundError: If the image path does not exist. ValueError: For invalid opacity or rectangle dimensions. """# Validate and load imageifisinstance(image,str):ifnotos.path.exists(image):raiseFileNotFoundError(f"Image path ('{image}') does not exist.")image=cv2.imread(image,cv2.IMREAD_UNCHANGED)# Validate opacityifnot0.0<=opacity<=1.0:raiseValueError("Opacity must be between 0.0 and 1.0.")# Validate rectangle dimensionsif(rect.x<0orrect.y<0orrect.x+rect.width>scene.shape[1]orrect.y+rect.height>scene.shape[0]):raiseValueError("Invalid rectangle dimensions.")# Resize and isolate alpha channelimage=cv2.resize(image,(rect.width,rect.height))alpha_channel=(image[:,:,3]ifimage.shape[2]==4elsenp.ones((rect.height,rect.width),dtype=image.dtype)*255)alpha_scaled=cv2.convertScaleAbs(alpha_channel*opacity)# Perform blendingscene_roi=scene[rect.y:rect.y+rect.height,rect.x:rect.x+rect.width]alpha_float=alpha_scaled.astype(np.float32)/255.0blended_roi=cv2.convertScaleAbs((1-alpha_float[...,np.newaxis])*scene_roi+alpha_float[...,np.newaxis]*image[:,:,:3])# Update the scenescene[rect.y:rect.y+rect.height,rect.x:rect.x+rect.width]=blended_roireturnscene
defcalculate_optimal_text_scale(resolution_wh:Tuple[int,int])->float:""" Calculate font scale based on the resolution of an image. Parameters: resolution_wh (Tuple[int, int]): A tuple representing the width and height of the image. Returns: float: The calculated font scale factor. """returnmin(resolution_wh)*1e-3
defcalculate_optimal_line_thickness(resolution_wh:Tuple[int,int])->int:""" Calculate line thickness based on the resolution of an image. Parameters: resolution_wh (Tuple[int, int]): A tuple representing the width and height of the image. Returns: int: The calculated line thickness in pixels. """ifmin(resolution_wh)<1080:return2return4
This class provides methods to work with colors, including creating colors from hex
codes, converting colors to hex strings, RGB tuples, and BGR tuples.
@dataclassclassColor:""" Represents a color in RGB format. This class provides methods to work with colors, including creating colors from hex codes, converting colors to hex strings, RGB tuples, and BGR tuples. Attributes: r (int): Red channel value (0-255). g (int): Green channel value (0-255). b (int): Blue channel value (0-255). Example: ```python import supervision as sv sv.Color.WHITE # Color(r=255, g=255, b=255) ``` | Constant | Hex Code | RGB | |------------|------------|------------------| | `WHITE` | `#FFFFFF` | `(255, 255, 255)`| | `BLACK` | `#000000` | `(0, 0, 0)` | | `RED` | `#FF0000` | `(255, 0, 0)` | | `GREEN` | `#00FF00` | `(0, 255, 0)` | | `BLUE` | `#0000FF` | `(0, 0, 255)` | | `YELLOW` | `#FFFF00` | `(255, 255, 0)` | | `ROBOFLOW` | `#A351FB` | `(163, 81, 251)` | """r:intg:intb:int@classmethoddeffrom_hex(cls,color_hex:str)->Color:""" Create a Color instance from a hex string. Args: color_hex (str): The hex string representing the color. This string can start with '#' followed by either 3 or 6 hexadecimal characters. In case of 3 characters, each character is repeated to form the full 6-character hex code. Returns: Color: An instance representing the color. Example: ```python import supervision as sv sv.Color.from_hex('#ff00ff') # Color(r=255, g=0, b=255) sv.Color.from_hex('#f0f') # Color(r=255, g=0, b=255) ``` """_validate_color_hex(color_hex)color_hex=color_hex.lstrip("#")iflen(color_hex)==3:color_hex="".join(c*2forcincolor_hex)r,g,b=(int(color_hex[i:i+2],16)foriinrange(0,6,2))returncls(r,g,b)@classmethoddeffrom_rgb_tuple(cls,color_tuple:Tuple[int,int,int])->Color:""" Create a Color instance from an RGB tuple. Args: color_tuple (Tuple[int, int, int]): A tuple representing the color in RGB format, where each element is an integer in the range 0-255. Returns: Color: An instance representing the color. Example: ```python import supervision as sv sv.Color.from_rgb_tuple((255, 255, 0)) # Color(r=255, g=255, b=0) ``` """r,g,b=color_tuplereturncls(r=r,g=g,b=b)@classmethoddeffrom_bgr_tuple(cls,color_tuple:Tuple[int,int,int])->Color:""" Create a Color instance from a BGR tuple. Args: color_tuple (Tuple[int, int, int]): A tuple representing the color in BGR format, where each element is an integer in the range 0-255. Returns: Color: An instance representing the color. Example: ```python import supervision as sv sv.Color.from_bgr_tuple((0, 255, 255)) # Color(r=255, g=255, b=0) ``` """b,g,r=color_tuplereturncls(r=r,g=g,b=b)defas_hex(self)->str:""" Converts the Color instance to a hex string. Returns: str: The hexadecimal color string. Example: ```python import supervision as sv sv.Color(r=255, g=255, b=0).as_hex() # '#ffff00' ``` """returnf"#{self.r:02x}{self.g:02x}{self.b:02x}"defas_rgb(self)->Tuple[int,int,int]:""" Returns the color as an RGB tuple. Returns: Tuple[int, int, int]: RGB tuple. Example: ```python import supervision as sv sv.Color(r=255, g=255, b=0).as_rgb() # (255, 255, 0) ``` """returnself.r,self.g,self.bdefas_bgr(self)->Tuple[int,int,int]:""" Returns the color as a BGR tuple. Returns: Tuple[int, int, int]: BGR tuple. Example: ```python import supervision as sv sv.Color(r=255, g=255, b=0).as_bgr() # (0, 255, 255) ``` """returnself.b,self.g,self.r@classpropertydefWHITE(cls)->Color:returnColor.from_hex("#FFFFFF")@classpropertydefBLACK(cls)->Color:returnColor.from_hex("#000000")@classpropertydefRED(cls)->Color:returnColor.from_hex("#FF0000")@classpropertydefGREEN(cls)->Color:returnColor.from_hex("#00FF00")@classpropertydefBLUE(cls)->Color:returnColor.from_hex("#0000FF")@classpropertydefYELLOW(cls)->Color:returnColor.from_hex("#FFFF00")@classpropertydefROBOFLOW(cls)->Color:returnColor.from_hex("#A351FB")def__hash__(self):returnhash((self.r,self.g,self.b))def__eq__(self,other):return(isinstance(other,Color)andself.r==other.randself.g==other.gandself.b==other.b)
defas_hex(self)->str:""" Converts the Color instance to a hex string. Returns: str: The hexadecimal color string. Example: ```python import supervision as sv sv.Color(r=255, g=255, b=0).as_hex() # '#ffff00' ``` """returnf"#{self.r:02x}{self.g:02x}{self.b:02x}"
@classmethoddeffrom_bgr_tuple(cls,color_tuple:Tuple[int,int,int])->Color:""" Create a Color instance from a BGR tuple. Args: color_tuple (Tuple[int, int, int]): A tuple representing the color in BGR format, where each element is an integer in the range 0-255. Returns: Color: An instance representing the color. Example: ```python import supervision as sv sv.Color.from_bgr_tuple((0, 255, 255)) # Color(r=255, g=255, b=0) ``` """b,g,r=color_tuplereturncls(r=r,g=g,b=b)
The hex string representing the color. This string can
start with '#' followed by either 3 or 6 hexadecimal characters. In
case of 3 characters, each character is repeated to form the full
6-character hex code.
@classmethoddeffrom_hex(cls,color_hex:str)->Color:""" Create a Color instance from a hex string. Args: color_hex (str): The hex string representing the color. This string can start with '#' followed by either 3 or 6 hexadecimal characters. In case of 3 characters, each character is repeated to form the full 6-character hex code. Returns: Color: An instance representing the color. Example: ```python import supervision as sv sv.Color.from_hex('#ff00ff') # Color(r=255, g=0, b=255) sv.Color.from_hex('#f0f') # Color(r=255, g=0, b=255) ``` """_validate_color_hex(color_hex)color_hex=color_hex.lstrip("#")iflen(color_hex)==3:color_hex="".join(c*2forcincolor_hex)r,g,b=(int(color_hex[i:i+2],16)foriinrange(0,6,2))returncls(r,g,b)
@classmethoddeffrom_rgb_tuple(cls,color_tuple:Tuple[int,int,int])->Color:""" Create a Color instance from an RGB tuple. Args: color_tuple (Tuple[int, int, int]): A tuple representing the color in RGB format, where each element is an integer in the range 0-255. Returns: Color: An instance representing the color. Example: ```python import supervision as sv sv.Color.from_rgb_tuple((255, 255, 0)) # Color(r=255, g=255, b=0) ``` """r,g,b=color_tuplereturncls(r=r,g=g,b=b)
@dataclassclassColorPalette:colors:List[Color]@classpropertydefDEFAULT(cls)->ColorPalette:""" Returns a default color palette. Returns: ColorPalette: A ColorPalette instance with default colors. Example: ```python import supervision as sv sv.ColorPalette.DEFAULT # ColorPalette(colors=[Color(r=255, g=64, b=64), Color(r=255, g=161, b=160), ...]) ```  """# noqa: E501 // docsreturnColorPalette.from_hex(color_hex_list=DEFAULT_COLOR_PALETTE)@classpropertydefROBOFLOW(cls)->ColorPalette:""" Returns a Roboflow color palette. Returns: ColorPalette: A ColorPalette instance with Roboflow colors. Example: ```python import supervision as sv sv.ColorPalette.ROBOFLOW # ColorPalette(colors=[Color(r=194, g=141, b=252), Color(r=163, g=81, b=251), ...]) ```  """# noqa: E501 // docsreturnColorPalette.from_hex(color_hex_list=ROBOFLOW_COLOR_PALETTE)@classpropertydefLEGACY(cls)->ColorPalette:returnColorPalette.from_hex(color_hex_list=LEGACY_COLOR_PALETTE)@classmethoddeffrom_hex(cls,color_hex_list:List[str])->ColorPalette:""" Create a ColorPalette instance from a list of hex strings. Args: color_hex_list (List[str]): List of color hex strings. Returns: ColorPalette: A ColorPalette instance. Example: ```python import supervision as sv sv.ColorPalette.from_hex(['#ff0000', '#00ff00', '#0000ff']) # ColorPalette(colors=[Color(r=255, g=0, b=0), Color(r=0, g=255, b=0), ...]) ``` """colors=[Color.from_hex(color_hex)forcolor_hexincolor_hex_list]returncls(colors)@classmethoddeffrom_matplotlib(cls,palette_name:str,color_count:int)->ColorPalette:""" Create a ColorPalette instance from a Matplotlib color palette. Args: palette_name (str): Name of the Matplotlib palette. color_count (int): Number of colors to sample from the palette. Returns: ColorPalette: A ColorPalette instance. Example: ```python import supervision as sv sv.ColorPalette.from_matplotlib('viridis', 5) # ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...]) ```  """# noqa: E501 // docsmpl_palette=plt.get_cmap(palette_name,color_count)ifhasattr(mpl_palette,"colors"):colors=mpl_palette.colorselse:colors=[mpl_palette(i/(color_count-1))foriinrange(color_count)]returncls([Color(int(r*255),int(g*255),int(b*255))forr,g,b,_incolors])defby_idx(self,idx:int)->Color:""" Return the color at a given index in the palette. Args: idx (int): Index of the color in the palette. Returns: Color: Color at the given index. Example: ```python import supervision as sv color_palette = sv.ColorPalette.from_hex(['#ff0000', '#00ff00', '#0000ff']) color_palette.by_idx(1) # Color(r=0, g=255, b=0) ``` """ifidx<0:raiseValueError("idx argument should not be negative")idx=idx%len(self.colors)returnself.colors[idx]def__len__(self)->int:""" Returns the number of colors in the palette. Returns: int: The number of colors. """returnlen(self.colors)
defby_idx(self,idx:int)->Color:""" Return the color at a given index in the palette. Args: idx (int): Index of the color in the palette. Returns: Color: Color at the given index. Example: ```python import supervision as sv color_palette = sv.ColorPalette.from_hex(['#ff0000', '#00ff00', '#0000ff']) color_palette.by_idx(1) # Color(r=0, g=255, b=0) ``` """ifidx<0:raiseValueError("idx argument should not be negative")idx=idx%len(self.colors)returnself.colors[idx]
@classmethoddeffrom_hex(cls,color_hex_list:List[str])->ColorPalette:""" Create a ColorPalette instance from a list of hex strings. Args: color_hex_list (List[str]): List of color hex strings. Returns: ColorPalette: A ColorPalette instance. Example: ```python import supervision as sv sv.ColorPalette.from_hex(['#ff0000', '#00ff00', '#0000ff']) # ColorPalette(colors=[Color(r=255, g=0, b=0), Color(r=0, g=255, b=0), ...]) ``` """colors=[Color.from_hex(color_hex)forcolor_hexincolor_hex_list]returncls(colors)
@classmethoddeffrom_matplotlib(cls,palette_name:str,color_count:int)->ColorPalette:""" Create a ColorPalette instance from a Matplotlib color palette. Args: palette_name (str): Name of the Matplotlib palette. color_count (int): Number of colors to sample from the palette. Returns: ColorPalette: A ColorPalette instance. Example: ```python import supervision as sv sv.ColorPalette.from_matplotlib('viridis', 5) # ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...]) ```  """# noqa: E501 // docsmpl_palette=plt.get_cmap(palette_name,color_count)ifhasattr(mpl_palette,"colors"):colors=mpl_palette.colorselse:colors=[mpl_palette(i/(color_count-1))foriinrange(color_count)]returncls([Color(int(r*255),int(g*255),int(b*255))forr,g,b,_incolors])