目前常用的基于siam孪生网络进行跟踪的算法常需要以第一帧的目标区域做为模板提取特征。再unity中实现这一功能是有意义的。
上一章我们已经实现了人工操作选择目标区域的功能,及已经拿到了bbox和image,我们在此工作基础上继续进行。值得实现说明的是,bbox的定义规则在大多数情况下都为(topleft.x,topleft.y,width,height),也是常用的coco的bbox的使用方式。在opencv中的矩形区域也是如此,在此做一统一。下面来看siam网络的初始化代码。
def initialize(self, image: np.ndarray, rect: np.array, **kwargs) -> None:
"""
args:
img(np.ndarray): RGB image
bbox(list): [x, y, width, height]
x, y need to be 0-based
"""
rect = clamp_bbox(rect, image.shape)
self.tracking_state.bbox = rect
self.tracking_state.mean_color = np.mean(image, axis=(0, 1))
template_crop, template_bbox, _ = get_extended_crop(
image=image,
bbox=rect,
offset=self.tracking_config["template_bbox_offset"],
crop_size=self.tracking_config["template_size"],
)
self._template_features = self.get_template_features(image, rect)
输入的image和bbox首先将经过clamp_bbox函数,该函数会判断bbox是否超过了image的范围。虽然我们在之前的实现中并不会出现这种情况,但以防万一我们还是将该函数也进行实现。原始python的代码是这样的
def clamp_bbox(bbox: np.array, shape: Tuple[int, int], min_side: int = 3) -> np.array:
"""
将边界框限制在图像范围内,并确保其宽度和高度不小于指定的最小尺寸。
参数:
bbox: np.array - 输入的边界框,以[x, y, width, height]格式表示。
shape: Tuple[int, int] - 图像的尺寸,格式为(高度, 宽度)。
min_side: int - 边界框的最小宽度和高度,默认为3。
返回:
np.array - 限制后的边界框,以[x, y, width, height]格式返回。
"""
# 确保边界框在图像边界内,调用辅助函数进行边界处理
bbox = ensure_bbox_boundaries(bbox, img_shape=shape)
# 解包边界框参数
x, y, w, h = bbox
# 获取图像的高度和宽度
img_h, img_w = shape[0], shape[1]