Spaces:
Runtime error
Runtime error
File size: 5,909 Bytes
cc0dd3c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# Copyright (c) OpenMMLab. All rights reserved.
from typing import Dict, List, Optional, Union
import cv2
import numpy as np
from mmcv import color_val
from ..node import Node
from ..registry import NODES
try:
import psutil
psutil_proc = psutil.Process()
except (ImportError, ModuleNotFoundError):
psutil_proc = None
@NODES.register_module()
class MonitorNode(Node):
"""Show diagnostic information.
Args:
name (str): The node name (also thread name)
input_buffer (str): The name of the input buffer
output_buffer (str|list): The name(s) of the output buffer(s)
enable_key (str|int, optional): Set a hot-key to toggle enable/disable
of the node. If an int value is given, it will be treated as an
ascii code of a key. Please note: (1) If ``enable_key`` is set,
the ``bypass()`` method need to be overridden to define the node
behavior when disabled; (2) Some hot-keys are reserved for
particular use. For example: 'q', 'Q' and 27 are used for exiting.
Default: ``None``
enable (bool): Default enable/disable status. Default: ``True``
x_offset (int): The position of the text box's left border in
pixels. Default: 20
y_offset (int): The position of the text box's top border in
pixels. Default: 20
y_delta (int): The line height in pixels. Default: 15
text_color (str|tuple): The font color represented in a color name or
a BGR tuple. Default: ``'black'``
backbround_color (str|tuple): The background color represented in a
color name or a BGR tuple. Default: (255, 183, 0)
text_scale (float): The font scale factor that is multiplied by the
base size. Default: 0.4
ignore_items (list[str], optional): Specify the node information items
that will not be shown. See ``MonitorNode._default_ignore_items``
for the default setting.
Example::
>>> cfg = dict(
... type='MonitorNode',
... name='monitor',
... enable_key='m',
... enable=False,
... input_buffer='vis_notice',
... output_buffer='display')
>>> from mmpose.apis.webcam.nodes import NODES
>>> node = NODES.build(cfg)
"""
_default_ignore_items = ['timestamp']
def __init__(self,
name: str,
input_buffer: str,
output_buffer: Union[str, List[str]],
enable_key: Optional[Union[str, int]] = None,
enable: bool = False,
x_offset=20,
y_offset=20,
y_delta=15,
text_color='black',
background_color=(255, 183, 0),
text_scale=0.4,
ignore_items: Optional[List[str]] = None):
super().__init__(name=name, enable_key=enable_key, enable=enable)
self.x_offset = x_offset
self.y_offset = y_offset
self.y_delta = y_delta
self.text_color = color_val(text_color)
self.background_color = color_val(background_color)
self.text_scale = text_scale
if ignore_items is None:
self.ignore_items = self._default_ignore_items
else:
self.ignore_items = ignore_items
self.register_input_buffer(input_buffer, 'input', trigger=True)
self.register_output_buffer(output_buffer)
def process(self, input_msgs):
input_msg = input_msgs['input']
input_msg.update_route_info(
node_name='System Info',
node_type='none',
info=self._get_system_info())
img = input_msg.get_image()
route_info = input_msg.get_route_info()
img = self._show_route_info(img, route_info)
input_msg.set_image(img)
return input_msg
def _get_system_info(self):
"""Get the system information including CPU and memory usage.
Returns:
dict: The system information items.
"""
sys_info = {}
if psutil_proc is not None:
sys_info['CPU(%)'] = psutil_proc.cpu_percent()
sys_info['Memory(%)'] = psutil_proc.memory_percent()
return sys_info
def _show_route_info(self, img: np.ndarray,
route_info: List[Dict]) -> np.ndarray:
"""Show the route information in the frame.
Args:
img (np.ndarray): The frame image.
route_info (list[dict]): The route information of the frame.
Returns:
np.ndarray: The processed image.
"""
canvas = np.full(img.shape, self.background_color, dtype=img.dtype)
x = self.x_offset
y = self.y_offset
max_len = 0
def _put_line(line=''):
nonlocal y, max_len
cv2.putText(canvas, line, (x, y), cv2.FONT_HERSHEY_DUPLEX,
self.text_scale, self.text_color, 1)
y += self.y_delta
max_len = max(max_len, len(line))
for node_info in route_info:
title = f'{node_info["node"]}({node_info["node_type"]})'
_put_line(title)
for k, v in node_info['info'].items():
if k in self.ignore_items:
continue
if isinstance(v, float):
v = f'{v:.1f}'
_put_line(f' {k}: {v}')
x1 = max(0, self.x_offset)
x2 = min(img.shape[1], int(x + max_len * self.text_scale * 20))
y1 = max(0, self.y_offset - self.y_delta)
y2 = min(img.shape[0], y)
src1 = canvas[y1:y2, x1:x2]
src2 = img[y1:y2, x1:x2]
img[y1:y2, x1:x2] = cv2.addWeighted(src1, 0.5, src2, 0.5, 0)
return img
def bypass(self, input_msgs):
return input_msgs['input']
|