def generate_all_anchors(self, im_c, size): if self.image_center == im_c and self.size == size: return False self.image_center = im_c self.size = size a0x = im_c - size // 2 * self.stride ori = np.array([a0x] * 4, dtype=np.float32) zero_anchors = self.anchors + ori x1 = zero_anchors[:, 0] y1 = zero_anchors[:, 1] x2 = zero_anchors[:, 2] y2 = zero_anchors[:, 3] x1, y1, x2, y2 = map(lambda x: x.reshape(self.anchor_num, 1, 1), [x1, y1, x2, y2]) cx, cy, w, h = corner2center([x1, y1, x2, y2]) disp_x = np.arange(0, size).reshape(1, 1, -1) * self.stride disp_y = np.arange(0, size).reshape(1, -1, 1) * self.stride cx = cx + disp_x cy = cy + disp_y # broadcast zero = np.zeros((self.anchor_num, size, size), dtype=np.float32) cx, cy, w, h = map(lambda x: x + zero, [cx, cy, w, h]) x1, y1, x2, y2 = center2corner([cx, cy, w, h]) self.all_anchors = np.stack([x1, y1, x2, y2]), np.stack([cx, cy, w, h]) return True
def generate_all_anchors(self, im_c, size): """ 生成整幅图像的anchors :param im_c:图像的中心点 :param size:图像的尺寸 :return: """ if self.image_center == im_c and self.size == size: return False # 更新config中的内容 self.image_center = im_c self.size = size # anchor0 的xy 坐标,即 x 和 y 对称。 a0x = im_c - size // 2 * self.stride # 生成anchor0的坐标 ori = np.array([a0x] * 4, dtype=np.float32) # 以图像中心点为中心点的anchor zero_anchors = self.anchors + ori # 获取anchor0的坐标 x1 = zero_anchors[:, 0] y1 = zero_anchors[:, 1] x2 = zero_anchors[:, 2] y2 = zero_anchors[:, 3] x1, y1, x2, y2 = map(lambda x: x.reshape(self.anchor_num, 1, 1), [x1, y1, x2, y2]) cx, cy, w, h = corner2center([x1, y1, x2, y2]) # disp_x是[1, 1, size],disp_y是[1, size, 1] disp_x = np.arange(0, size).reshape(1, 1, -1) * self.stride disp_y = np.arange(0, size).reshape(1, -1, 1) * self.stride # 得到整幅图像中anchor中心点的坐标 cx = cx + disp_x cy = cy + disp_y # 通过广播生成整幅图像的anchor broadcast zero = np.zeros((self.anchor_num, size, size), dtype=np.float32) cx, cy, w, h = map(lambda x: x + zero, [cx, cy, w, h]) x1, y1, x2, y2 = center2corner([cx, cy, w, h]) # 以中心点坐标,宽高和左上角、右下角坐标两种方式存储anchors self.all_anchors = np.stack([x1, y1, x2, y2]), np.stack([cx, cy, w, h]) return True
def generate_all_anchors(self, im_c, size): if self.image_center == im_c and self.size == size: return False self.image_center = im_c self.size = size # size到底代表啥 # 下面的一行是说:size是search image经过孪生网络后、再经过depth-wise的xcorr后的feature map的大小(17x17),从论文中可以看出stride=16(相当于经过四次下采样) # 而feature map左上角 第一个点 对应的在输入孪生网络前的search image里的横/纵坐标值就是下面的公式计算的值 # 而计算出来的a0x就是一个锚点,一个锚点就可以产生一系列的anchors a0x = im_c - size // 2 * self.stride ori = np.array([a0x] * 4, dtype=np.float32) zero_anchors = self.anchors + ori # 这里的加法存在广播机制; generate_anchors里面产生的是相对坐标,作为中心是0; # 这里我们要给出锚点的绝对中心,才能得到绝对坐标 x1 = zero_anchors[:, 0] y1 = zero_anchors[:, 1] x2 = zero_anchors[:, 2] y2 = zero_anchors[:, 3] x1, y1, x2, y2 = map(lambda x: x.reshape(self.anchor_num, 1, 1), [x1, y1, x2, y2]) cx, cy, w, h = corner2center([x1, y1, x2, y2]) disp_x = np.arange(0, size).reshape(1, 1, -1) * self.stride disp_y = np.arange(0, size).reshape(1, -1, 1) * self.stride cx = cx + disp_x cy = cy + disp_y # broadcast zero = np.zeros((self.anchor_num, size, size), dtype=np.float32) # 从这里我们可以看到,zero的第零个维度方向代表的是anchor的种类(种类包括不同的横纵比,尺度scale,密度) # 第一、二个维度方向代表的是每个锚点(即feature map点,要区别于anchor)针对于第零维度上某一类anchor的具体的横纵坐标值 cx, cy, w, h = map( lambda x: x + zero, [cx, cy, w, h ]) # 这四个值的每一个都需要一个shape=(self.anchor_num, size, size)的ndarray来描述 x1, y1, x2, y2 = center2corner([cx, cy, w, h]) self.all_anchors = np.stack([x1, y1, x2, y2]), np.stack( [cx, cy, w, h]) # np.stack就是摞起来了,多了一个维度方向;注意和np.cat的区别; return True # 返回来的是tuple,第一个元素是两坐标表示法的anchor信息;第二个是中心做标加h,w