Add method to free buffers
Browse files- rtmo_gpu.py +21 -20
rtmo_gpu.py
CHANGED
@@ -1,11 +1,14 @@
|
|
1 |
import os
|
2 |
import numpy as np
|
3 |
-
from typing import List, Tuple
|
4 |
import onnxruntime as ort
|
5 |
import cv2
|
6 |
from queue import Queue
|
7 |
-
|
|
|
|
|
8 |
TRT_BACKEND='POLYGRAPHY'
|
|
|
9 |
|
10 |
# dictionary from https://github.com/Tau-J/rtmlib/blob/4b29101d54b611048ef165277cebfffff3030074/rtmlib/visualization/skeleton/coco17.py
|
11 |
coco17 = dict(name='coco17',
|
@@ -307,7 +310,7 @@ def get_model_format_and_input_shape(model):
|
|
307 |
elif is_trt_engine(model):
|
308 |
model_format = 'engine'
|
309 |
from polygraphy.backend.trt import load_plugins
|
310 |
-
load_plugins(plugins=[
|
311 |
input_shape = get_trt_input_shapes(model)['input']
|
312 |
else:
|
313 |
raise TypeError("Your model is neither ONNX nor Engine !")
|
@@ -317,10 +320,8 @@ class RTMO_GPU(object):
|
|
317 |
|
318 |
def preprocess(self, img: np.ndarray):
|
319 |
"""Do preprocessing for RTMPose model inference.
|
320 |
-
|
321 |
Args:
|
322 |
img (np.ndarray): Input image in shape.
|
323 |
-
|
324 |
Returns:
|
325 |
tuple:
|
326 |
- resized_img (np.ndarray): Preprocessed image.
|
@@ -358,17 +359,13 @@ class RTMO_GPU(object):
|
|
358 |
ratio: float = 1.,
|
359 |
) -> Tuple[np.ndarray, np.ndarray]:
|
360 |
"""Do postprocessing for RTMO model inference.
|
361 |
-
|
362 |
Args:
|
363 |
outputs (List[np.ndarray]): Outputs of RTMO model.
|
364 |
ratio (float): Ratio of preprocessing.
|
365 |
-
|
366 |
Returns:
|
367 |
tuple:
|
368 |
- final_boxes (np.ndarray): Final bounding boxes.
|
369 |
- final_scores (np.ndarray): Final scores.
|
370 |
-
- final keypoints
|
371 |
-
- final keypoints scores
|
372 |
"""
|
373 |
|
374 |
if not self.is_yolo_nas_pose:
|
@@ -408,10 +405,8 @@ class RTMO_GPU(object):
|
|
408 |
|
409 |
def inference(self, img: np.ndarray):
|
410 |
"""Inference model.
|
411 |
-
|
412 |
Args:
|
413 |
img (np.ndarray): Input image in shape.
|
414 |
-
|
415 |
Returns:
|
416 |
outputs (np.ndarray): Output of RTMPose model.
|
417 |
"""
|
@@ -496,7 +491,7 @@ class RTMO_GPU(object):
|
|
496 |
device: str = 'cuda',
|
497 |
is_yolo_nas_pose = False,
|
498 |
batch_size = 1,
|
499 |
-
plugin_path =
|
500 |
|
501 |
self.batch_size = batch_size
|
502 |
|
@@ -595,10 +590,8 @@ class RTMO_GPU(object):
|
|
595 |
class RTMO_GPU_Batch(RTMO_GPU):
|
596 |
def preprocess_batch(self, imgs: List[np.ndarray]) -> Tuple[np.ndarray, List[float]]:
|
597 |
"""Process a batch of images for RTMPose model inference.
|
598 |
-
|
599 |
Args:
|
600 |
imgs (List[np.ndarray]): List of input images.
|
601 |
-
|
602 |
Returns:
|
603 |
tuple:
|
604 |
- batch_img (np.ndarray): Batch of preprocessed images.
|
@@ -619,10 +612,8 @@ class RTMO_GPU_Batch(RTMO_GPU):
|
|
619 |
|
620 |
def inference(self, batch_img: np.ndarray):
|
621 |
"""Override to handle batch inference.
|
622 |
-
|
623 |
Args:
|
624 |
batch_img (np.ndarray): Batch of preprocessed images.
|
625 |
-
|
626 |
Returns:
|
627 |
outputs (List[np.ndarray]): Outputs of RTMPose model for each image.
|
628 |
"""
|
@@ -690,11 +681,9 @@ class RTMO_GPU_Batch(RTMO_GPU):
|
|
690 |
ratios: List[float]
|
691 |
) -> Tuple[List[np.ndarray], List[np.ndarray]]:
|
692 |
"""Process outputs for a batch of images.
|
693 |
-
|
694 |
Args:
|
695 |
outputs (List[np.ndarray]): Outputs from the model for each image.
|
696 |
ratios (List[float]): Ratios used for preprocessing each image.
|
697 |
-
|
698 |
Returns:
|
699 |
List[Tuple[np.ndarray, np.ndarray]]: keypoints and scores for each image.
|
700 |
"""
|
@@ -720,6 +709,15 @@ class RTMO_GPU_Batch(RTMO_GPU):
|
|
720 |
bboxes, bboxes_scores, keypoints, scores = self.postprocess_batch(outputs, ratios)
|
721 |
return bboxes, bboxes_scores, keypoints, scores
|
722 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
723 |
def __call__(self, image: np.array, camera_id = 0):
|
724 |
|
725 |
# initialize dedicated buffers & queues for camera with id "camera_id"
|
@@ -727,6 +725,9 @@ class RTMO_GPU_Batch(RTMO_GPU):
|
|
727 |
self.buffers[camera_id] = []
|
728 |
self.in_queues[camera_id] = Queue(maxsize=self.batch_size)
|
729 |
self.out_queues[camera_id] = Queue(maxsize=self.batch_size)
|
|
|
|
|
|
|
730 |
|
731 |
in_queue = self.in_queues[camera_id]
|
732 |
out_queue = self.out_queues[camera_id]
|
@@ -755,7 +756,7 @@ class RTMO_GPU_Batch(RTMO_GPU):
|
|
755 |
std: tuple = None,
|
756 |
device: str = 'cuda',
|
757 |
is_yolo_nas_pose = False,
|
758 |
-
plugin_path =
|
759 |
batch_size: int = 1):
|
760 |
super().__init__(model,
|
761 |
mean,
|
@@ -786,4 +787,4 @@ def resize_to_fit_screen(image, screen_width, screen_height):
|
|
786 |
# Resize the image
|
787 |
resized_image = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA)
|
788 |
|
789 |
-
return resized_image
|
|
|
1 |
import os
|
2 |
import numpy as np
|
3 |
+
from typing import List, Tuple, Union
|
4 |
import onnxruntime as ort
|
5 |
import cv2
|
6 |
from queue import Queue
|
7 |
+
|
8 |
+
PLUGIN_LIB_PATHS='libmmdeploy_tensorrt_ops.so'
|
9 |
+
os.environ['ORT_TENSORRT_EXTRA_PLUGIN_LIB_PATHS']=PLUGIN_LIB_PATHS
|
10 |
TRT_BACKEND='POLYGRAPHY'
|
11 |
+
DEBUG=False
|
12 |
|
13 |
# dictionary from https://github.com/Tau-J/rtmlib/blob/4b29101d54b611048ef165277cebfffff3030074/rtmlib/visualization/skeleton/coco17.py
|
14 |
coco17 = dict(name='coco17',
|
|
|
310 |
elif is_trt_engine(model):
|
311 |
model_format = 'engine'
|
312 |
from polygraphy.backend.trt import load_plugins
|
313 |
+
load_plugins(plugins=[PLUGIN_LIB_PATHS])
|
314 |
input_shape = get_trt_input_shapes(model)['input']
|
315 |
else:
|
316 |
raise TypeError("Your model is neither ONNX nor Engine !")
|
|
|
320 |
|
321 |
def preprocess(self, img: np.ndarray):
|
322 |
"""Do preprocessing for RTMPose model inference.
|
|
|
323 |
Args:
|
324 |
img (np.ndarray): Input image in shape.
|
|
|
325 |
Returns:
|
326 |
tuple:
|
327 |
- resized_img (np.ndarray): Preprocessed image.
|
|
|
359 |
ratio: float = 1.,
|
360 |
) -> Tuple[np.ndarray, np.ndarray]:
|
361 |
"""Do postprocessing for RTMO model inference.
|
|
|
362 |
Args:
|
363 |
outputs (List[np.ndarray]): Outputs of RTMO model.
|
364 |
ratio (float): Ratio of preprocessing.
|
|
|
365 |
Returns:
|
366 |
tuple:
|
367 |
- final_boxes (np.ndarray): Final bounding boxes.
|
368 |
- final_scores (np.ndarray): Final scores.
|
|
|
|
|
369 |
"""
|
370 |
|
371 |
if not self.is_yolo_nas_pose:
|
|
|
405 |
|
406 |
def inference(self, img: np.ndarray):
|
407 |
"""Inference model.
|
|
|
408 |
Args:
|
409 |
img (np.ndarray): Input image in shape.
|
|
|
410 |
Returns:
|
411 |
outputs (np.ndarray): Output of RTMPose model.
|
412 |
"""
|
|
|
491 |
device: str = 'cuda',
|
492 |
is_yolo_nas_pose = False,
|
493 |
batch_size = 1,
|
494 |
+
plugin_path = PLUGIN_LIB_PATHS):
|
495 |
|
496 |
self.batch_size = batch_size
|
497 |
|
|
|
590 |
class RTMO_GPU_Batch(RTMO_GPU):
|
591 |
def preprocess_batch(self, imgs: List[np.ndarray]) -> Tuple[np.ndarray, List[float]]:
|
592 |
"""Process a batch of images for RTMPose model inference.
|
|
|
593 |
Args:
|
594 |
imgs (List[np.ndarray]): List of input images.
|
|
|
595 |
Returns:
|
596 |
tuple:
|
597 |
- batch_img (np.ndarray): Batch of preprocessed images.
|
|
|
612 |
|
613 |
def inference(self, batch_img: np.ndarray):
|
614 |
"""Override to handle batch inference.
|
|
|
615 |
Args:
|
616 |
batch_img (np.ndarray): Batch of preprocessed images.
|
|
|
617 |
Returns:
|
618 |
outputs (List[np.ndarray]): Outputs of RTMPose model for each image.
|
619 |
"""
|
|
|
681 |
ratios: List[float]
|
682 |
) -> Tuple[List[np.ndarray], List[np.ndarray]]:
|
683 |
"""Process outputs for a batch of images.
|
|
|
684 |
Args:
|
685 |
outputs (List[np.ndarray]): Outputs from the model for each image.
|
686 |
ratios (List[float]): Ratios used for preprocessing each image.
|
|
|
687 |
Returns:
|
688 |
List[Tuple[np.ndarray, np.ndarray]]: keypoints and scores for each image.
|
689 |
"""
|
|
|
709 |
bboxes, bboxes_scores, keypoints, scores = self.postprocess_batch(outputs, ratios)
|
710 |
return bboxes, bboxes_scores, keypoints, scores
|
711 |
|
712 |
+
def free_unused_buffers(self, activate_cameras_ids: List):
|
713 |
+
for camera_id in list(self.buffers.keys()):
|
714 |
+
if camera_id not in activate_cameras_ids:
|
715 |
+
del self.buffers[camera_id]
|
716 |
+
del self.in_queues[camera_id]
|
717 |
+
del self.out_queues[camera_id]
|
718 |
+
if DEBUG:
|
719 |
+
print(f'RTMO buffers to camera "{camera_id}" got freed.', flush=True)
|
720 |
+
|
721 |
def __call__(self, image: np.array, camera_id = 0):
|
722 |
|
723 |
# initialize dedicated buffers & queues for camera with id "camera_id"
|
|
|
725 |
self.buffers[camera_id] = []
|
726 |
self.in_queues[camera_id] = Queue(maxsize=self.batch_size)
|
727 |
self.out_queues[camera_id] = Queue(maxsize=self.batch_size)
|
728 |
+
if DEBUG:
|
729 |
+
print(f'RTMO buffers to camera "{camera_id}" are created.', flush=True)
|
730 |
+
|
731 |
|
732 |
in_queue = self.in_queues[camera_id]
|
733 |
out_queue = self.out_queues[camera_id]
|
|
|
756 |
std: tuple = None,
|
757 |
device: str = 'cuda',
|
758 |
is_yolo_nas_pose = False,
|
759 |
+
plugin_path = PLUGIN_LIB_PATHS,
|
760 |
batch_size: int = 1):
|
761 |
super().__init__(model,
|
762 |
mean,
|
|
|
787 |
# Resize the image
|
788 |
resized_image = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA)
|
789 |
|
790 |
+
return resized_image
|