mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	* update onnxruntime * support for yolo-nas in openvino * cleanup notebook * update docs * improve docs * handle AUTO issue and update docs
		
			
				
	
	
		
			82 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import logging
 | 
						|
from abc import ABC, abstractmethod
 | 
						|
from typing import List
 | 
						|
 | 
						|
import numpy as np
 | 
						|
 | 
						|
from frigate.detectors.detector_config import ModelTypeEnum
 | 
						|
 | 
						|
logger = logging.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
class DetectionApi(ABC):
 | 
						|
    type_key: str
 | 
						|
    supported_models: List[ModelTypeEnum]
 | 
						|
 | 
						|
    @abstractmethod
 | 
						|
    def __init__(self, detector_config):
 | 
						|
        self.detector_config = detector_config
 | 
						|
        self.thresh = 0.5
 | 
						|
        self.height = detector_config.model.height
 | 
						|
        self.width = detector_config.model.width
 | 
						|
 | 
						|
    @abstractmethod
 | 
						|
    def detect_raw(self, tensor_input):
 | 
						|
        pass
 | 
						|
 | 
						|
    def post_process_yolonas(self, output):
 | 
						|
        """
 | 
						|
        @param output: output of inference
 | 
						|
        expected shape: [np.array(1, N, 4), np.array(1, N, 80)]
 | 
						|
        where N depends on the input size e.g. N=2100 for 320x320 images
 | 
						|
 | 
						|
        @return: best results: np.array(20, 6) where each row is
 | 
						|
        in this order (class_id, score, y1/height, x1/width, y2/height, x2/width)
 | 
						|
        """
 | 
						|
 | 
						|
        N = output[0].shape[1]
 | 
						|
 | 
						|
        boxes = output[0].reshape(N, 4)
 | 
						|
        scores = output[1].reshape(N, 80)
 | 
						|
 | 
						|
        class_ids = np.argmax(scores, axis=1)
 | 
						|
        scores = scores[np.arange(N), class_ids]
 | 
						|
 | 
						|
        args_best = np.argwhere(scores > self.thresh)[:, 0]
 | 
						|
 | 
						|
        num_matches = len(args_best)
 | 
						|
        if num_matches == 0:
 | 
						|
            return np.zeros((20, 6), np.float32)
 | 
						|
        elif num_matches > 20:
 | 
						|
            args_best20 = np.argpartition(scores[args_best], -20)[-20:]
 | 
						|
            args_best = args_best[args_best20]
 | 
						|
 | 
						|
        boxes = boxes[args_best]
 | 
						|
        class_ids = class_ids[args_best]
 | 
						|
        scores = scores[args_best]
 | 
						|
 | 
						|
        boxes = np.transpose(
 | 
						|
            np.vstack(
 | 
						|
                (
 | 
						|
                    boxes[:, 1] / self.height,
 | 
						|
                    boxes[:, 0] / self.width,
 | 
						|
                    boxes[:, 3] / self.height,
 | 
						|
                    boxes[:, 2] / self.width,
 | 
						|
                )
 | 
						|
            )
 | 
						|
        )
 | 
						|
 | 
						|
        results = np.hstack(
 | 
						|
            (class_ids[..., np.newaxis], scores[..., np.newaxis], boxes)
 | 
						|
        )
 | 
						|
 | 
						|
        return np.resize(results, (20, 6))
 | 
						|
 | 
						|
    def post_process(self, output):
 | 
						|
        if self.detector_config.model.model_type == ModelTypeEnum.yolonas:
 | 
						|
            return self.post_process_yolonas(output)
 | 
						|
        else:
 | 
						|
            raise ValueError(
 | 
						|
                f'Model type "{self.detector_config.model.model_type}" is currently not supported.'
 | 
						|
            )
 |