score map的生成(卷积运算)
def Xcorr(self, x, z):
out = []
for i in range(x.size(0)):
out.append(F.conv2d(x[i, :, :, :].unsqueeze(0), z[i, :, :, :].unsqueeze(0)))
return torch.cat(out, dim=0)
注意此卷积运算应为每个batch中,每一张图片分别做卷积运算
输入数据的处理
z和x的选择
n=len(img_files)
frame_range = 100
def sample_pair(self, n):
rand_z = np.random.randint(n) # select a image randomly as z(template)
if self.frame_range == 0:
return rand_z, rand_z
possible_x = np.arange(rand_z - self.frame_range, rand_z + self.frame_range) # get possible search(x) according to frame_range
possible_x = np.intersect1d(possible_x, np.arange(n)) # remove impossible x(search)
possible_x = possible_x[possible_x != rand_z] # z(template) and x(search) cannot be same
rand_x = np.random.choice(possible_x) # select x from possible_x randomly
return rand_z, rand_x
z和x的尺寸构建
SiameseFC需要的输入数据有模版图片z和候选图片x。
模版图片z的构建:
构建模版图片时,知道当前帧的bbox。
训练时,所有图片的bbox都是已知的。
预测时,第一帧bbox已知的,且预测是顺序预测,因此,预测过程中,预测帧前一帧的bbox是已知的。
总体过程:
以bbox的中心为中心,构建一个面积为127*127的区域,其中包括bbox周围环境信息,如果超出图片范围则通过像素平均值进行填充。
# crop the image patch of the specified size - template(127), search(255)
def crop(self, image, bndbox, out_size):
center = bndbox[:2] + bndbox[2:] / 2 #中心坐标
size = bndbox[2:
context = self.context * size.sum() #context就是添加边界的宽度,即上述公式中的2p
patch_sz = out_size / self.exemplarSize * \
np.sqrt((size + context).prod())
return crop_pil(image, center, patch_sz, out_size=out_size)
会发现虽然现在区域面积为127x127,但是他并不是127x127的方形,所以需要进行resize。
候选图片x的构建:
构建时已知其上一帧bbox的信息。
总体过程:
以上一帧bbox的中心为中心,构建一个面积为255*255的区域,如果超出范围则通过平均值进行pad。
将该区域resize为255*255。(上一步中的长宽可能不是255)
构建255*255区域与构建模版图片z时采用相同的缩放比例。
此时每对模板图像和搜索图像中心就是物体的bounding box中心!
这有什么好处呢?
答:我们在训练的时候,每次把模板图像滑到搜索图像的中心的时候,这时候会有最大的相似度,这为网络输出的真实值/标签设置,省了很多功夫!
计算loss
输入有三个部分:$score(B × 17 × 17), gt (B × 17 × 17 ), weight((1 × 17 × 17 )$。B为batch_size,gt代表ground truth,对于每个通道值都一样,靠近中心位置全部置1,代表是正样本。其余位置都是0,代表负样本。所有gt通道结果如下: