Пример #1
0
def draw_corspd_region_torch(img0, img1, H):
    """
    img0: [3, H_0, W_0]
    img1: [3, H_1, W_1]
    """
    img0 = (tonumpy(unnormalize(img0)) * 255.).astype(np.uint8)  # [H0, W0, 3]
    img1 = (tonumpy(unnormalize(img1)) * 255.).astype(np.uint8)  # [H1, W1, 3]
    if isinstance(H, torch.Tensor):
        H = H.detach().cpu().numpy()

    h1, w1 = img1.shape[:2]
    pts1 = np.array(
        [[0, 0],
         [0, h1],
         [w1, h1],
         [w1, 0]]
    ).astype(np.float32)
    pts0 = cv2.perspectiveTransform(np.reshape(pts1, [1, -1, 2]), np.linalg.inv(H))[0]

    # draw the corresponding region on the image
    pts0 = pts0.astype(np.int32)
    img0 = cv2.polylines(img0.copy(), [pts0.reshape([-1, 2])], True, (255, 0, 0), thickness=5)
    pts1 = pts1.astype(np.int32)
    img1 = cv2.polylines(img1.copy(), [pts1.reshape([-1, 2])], True, (255, 0, 0), thickness=5)

    return np.concatenate([img0, img1], axis=1)
Пример #2
0
def draw_img_desc_torch(img, desc):
    """
    img: [3, H, W]
    desc: [C, H, W]
    """
    img = (tonumpy(unnormalize(img)) * 255.).astype(np.uint8)  # [H, W, 3]
    desc = (desc2RGB(tonumpy(desc)) * 255.).astype(np.uint8)  # [H, W, 3]
    h, w = img.shape[:2]
    desc = cv2.resize(desc.copy(), (w, h), interpolation=cv2.INTER_LINEAR)
    return np.concatenate([img, desc], axis=1)
Пример #3
0
def draw_paired_desc_torch(desc0, kps0, image0, desc1, kps1, image1, H):
    """
    desc0: [C, H_0', W_0']
    kps0: [N, 2]
    image0: [3, H_0, W_0]
    desc1: [C, H_1', W_1']
    kps1: [N, 2]
    image1: [3, H_1, W_1]
    H: [3, 3]
    """
    desc0 = (desc2RGB(tonumpy(desc0)) * 255.).astype(np.uint8)  # [H, W, 3]
    kps0 = kps0.detach().cpu().numpy()
    desc1 = (desc2RGB(tonumpy(desc1)) * 255.).astype(np.uint8)
    kps1 = kps1.detach().cpu().numpy()

    # compute the corresponding region
    H = H.detach().cpu().numpy()
    h1, w1 = image1.shape[1:]
    pts1 = np.array(
        [[0, 0],
         [0, h1],
         [w1, h1],
         [w1, 0]]
    ).astype(np.float32)
    pts0 = cv2.perspectiveTransform(np.reshape(pts1, [1, -1, 2]), np.linalg.inv(H))[0]

    # compute the ratio between desc and image, and rescale the kps
    ratio_h0 = desc0.shape[0] / image0.shape[1]  # [H_0', W_0', 3], [3, H_0, W_0]
    ratio_w0 = desc0.shape[1] / image0.shape[2]
    pts0 *= np.array([[ratio_w0, ratio_h0]])
    ratio_h1 = desc1.shape[0] / image1.shape[1]
    ratio_w1 = desc1.shape[1] / image1.shape[2]
    pts1 *= np.array([[ratio_w1, ratio_h1]])

    # draw the corresponding region on the image
    pts0 = pts0.astype(np.int32)
    desc0 = cv2.polylines(desc0.copy(), [pts0.reshape([-1, 2])], True, (255, 0, 0), thickness=5)
    pts1 = pts1.astype(np.int32)
    desc1 = cv2.polylines(desc1.copy(), [pts1.reshape([-1, 2])], True, (255, 0, 0), thickness=5)

    # draw correspondences
    desc = draw_corr(desc0, kps0, desc1, kps1, num=10)
    desc = totensor(tofloat(desc))

    return desc
Пример #4
0
def draw_paired_img_desc_torch(img0, desc0, kps0, img1, desc1, kps1, H):
    """
    img0: [3, H_0, W_0]
    desc0: [C, H_0', W_0']
    kps0: [N, 2]
    img1: [3, H_1, W_1]
    desc1: [C, H_1', W_1']
    kps1: [N, 2]
    H: [3, 3]
    """
    img0 = (tonumpy(unnormalize(img0)) * 255.).astype(np.uint8)  # [H, W, 3]
    desc0 = (desc2RGB(tonumpy(desc0)) * 255.).astype(np.uint8)  # [H, W, 3]
    kps0 = kps0.detach().cpu().numpy()
    img1 = (tonumpy(unnormalize(img1)) * 255.).astype(np.uint8)
    desc1 = (desc2RGB(tonumpy(desc1)) * 255.).astype(np.uint8)
    kps1 = kps1.detach().cpu().numpy()

    # compute the corresponding region
    H = H.detach().cpu().numpy()
    h1, w1 = img1.shape[:2]
    pts1 = np.array(
        [[0, 0],
         [0, h1],
         [w1, h1],
         [w1, 0]]
    ).astype(np.float32)
    pts0 = cv2.perspectiveTransform(np.reshape(pts1, [1, -1, 2]), np.linalg.inv(H))[0]

    # draw the corresponding region on the image
    pts0 = pts0.astype(np.int32)
    img0 = cv2.polylines(img0.copy(), [pts0.reshape([-1, 2])], True, (255, 0, 0), thickness=5)
    desc0 = cv2.polylines(desc0.copy(), [pts0.reshape([-1, 2])], True, (255, 0, 0), thickness=5)
    # desc0 = cv2.warpPerspective(desc0.copy(), H, (w1, h1), flags=cv2.INTER_LINEAR)
    pts1 = pts1.astype(np.int32)
    img1 = cv2.polylines(img1.copy(), [pts1.reshape([-1, 2])], True, (255, 0, 0), thickness=5)
    desc1 = cv2.polylines(desc1.copy(), [pts1.reshape([-1, 2])], True, (255, 0, 0), thickness=5)

    # draw correspondences
    img = draw_corr(img0, kps0, img1, kps1, num=10)
    # desc = draw_corr(desc0, kps0, desc1, kps1, num=10)
    desc = draw_corr(desc0, kps1, desc1, kps1, num=10)
    return np.concatenate([img, desc], axis=0)
Пример #5
0
    def evaluate(self, scale_pred, scale, image0, image1, index, mask):
        """
        scale_pred: [3, H', W']
        scale: [1, H, W]
        image0: [3, H, W]
        image1: [3, H, W]
        mask: [1, H, W], boolean tensor
        """
        num_cls = scale_pred.shape[0]
        scale_pred = torch.argmax(scale_pred, dim=0).long()

        scale[scale > 1.5] = 2
        scale[scale < 0.75] = 0
        scale[(scale >= 0.75) * (scale <= 1.5)] = 1
        scale = scale.long()

        h, w = scale_pred.shape
        h0, w0 = scale.shape[1:]
        scale = F.interpolate(scale.view(1, 1, h0, w0).float(), (h, w),
                              mode='bilinear').long()[0, 0]
        mask = F.interpolate(mask.view(1, 1, h0, w0).float(), (h, w),
                             mode='bilinear').byte()[0, 0]

        # correct predictions
        correct = (scale_pred == scale) & mask
        accuracy = torch.sum(correct).float() / torch.sum(mask).float()
        self.accuracies.append(accuracy)

        scale_pred = touint8(tonumpy(cls2RGB(scale_pred, num_cls)))
        scale = touint8(tonumpy(cls2RGB(scale, num_cls)))

        img0 = tensor2RGB(image0)
        img1 = tensor2RGB(image1)
        img = np.concatenate([img0, img1], axis=1)

        import matplotlib.pyplot as plt
        _, (ax1, ax2, ax3) = plt.subplots(1, 3)
        ax1.imshow(img)
        ax2.imshow(scale)
        ax3.imshow(scale_pred)
        plt.show()
Пример #6
0
def draw_corr_torch(img0, pix_pos0, img1, pix_pos1):
    """
    Draw matches, torch version. Parameters are the same as draw keypoints
    """

    img0, img1 = [tonumpy(x) for x in [img0, img1]]
    img0, img1 = [touint8(x).astype(np.uint8) for x in [img0, img1]]
    pix_pos0, pix_pos1 = [x.numpy() for x in [pix_pos0, pix_pos1]]

    img = draw_corr(img0, pix_pos0, img1, pix_pos1)
    img = totensor(tofloat(img))
    return img
Пример #7
0
def draw_kps_torch(img0, pix_pos0, img1, pix_pos1):
    """
    Draw keypoints, torch version
    :param img0: (C, H, W)
    :param pix_pos0: (N, 2), (x, y)
    :param img1:  (C, H, W)
    :param pix_pos1: (N, 2), (x, y)
    :return: a single torch image
    """
    img0, img1 = [tonumpy(x) for x in [img0, img1]]
    img0, img1 = [touint8(x) for x in [img0, img1]]
    pix_pos0, pix_pos1 = [x.numpy() for x in [pix_pos0, pix_pos1]]
    
    img = draw_kps(img0, pix_pos0, img1, pix_pos1)
    img = totensor(tofloat(img))
    return img
Пример #8
0
    def get_tensorboard_data(self, num_kps=20):
        """
        This processes the data needed for visualization. It expects the follow-
        ing in self.logger
        
        - image0: (C, H, W), Tensor, normalized
        - image1: (C, H, W), Tensor, normalized
        - desc0: (C, H, W)
        - desc1: (C, H, W)
        - kps0: (N, 2), each being (x, y)
        - kps1: (N, 2)
        - kps2: (N, 2), negative ones
        
        And it returns a dictionary
        
        - desc0: descriptor 1, RGB, (3, H, W)
        - desc1: descriptor 2, RGB, (3, H, W)
        - img0: image 1, (3, H, W)
        - img1: image 2, (3, H, W)
        - keypoints: the two images marked with num_kps keypoints
        - neg_keypoints: image 2 marked with negative keypoints
        - corr: ground truth correspondences
        - corr false: false correspondences
        """

        # original images
        image0 = self.logger['image0']
        image1 = self.logger['image1']

        # descriptors
        desc0 = self.logger['desc0']
        desc1 = self.logger['desc1']

        # keypoints
        kps0 = self.logger['kps0']
        kps1 = self.logger['kps1']
        kps2 = self.logger['kps2']

        # process the images
        image0 = unnormalize(image0)
        image1 = unnormalize(image1)

        # process the descriptor
        desc0, desc1 = [desc2RGB(tonumpy(x)) for x in [desc0, desc1]]
        desc0, desc1 = [totensor(d) for d in [desc0, desc1]]

        # choose keypoints
        N = kps0.shape[0]
        indices = np.random.choice(N, size=num_kps, replace=False)

        # draw keypoints
        kps = draw_kps_torch(image0, kps0[indices], image1, kps1[indices])

        # draw negative keypoints
        neg_kps = draw_kps_torch(image0, kps0[indices], image1, kps2[indices])

        # draw correspondences
        corr_gt = draw_corr_torch(image0, kps0[indices], image1, kps1[indices])

        # draw correspondences
        corr_false = draw_corr_torch(image0, kps0[indices], image1,
                                     kps2[indices])

        return {
            'img0': image0,
            'img1': image1,
            'desc0': desc0,
            'desc1': desc1,
            'keypoints': kps,
            'neg_keypoints': neg_kps,
            'corr': corr_gt,
            'corr_false': corr_false
        }