コード例 #1
0
    def generate_triplets(self):
        """
            Generate train test clusters
            Sample multiple views per cluster in both train and test clusters
            Iterate over train test clusters
                Iterate over ref_view in sample_ref_views:
                    Generate Neighbors
                    Sample Neighbors
                    Iterate over sample_neighbors over generate_neighbors
                        Iterate over each bounding box
        """
        if self.ref_views is None:
            self.sample_ref_views()

        proposals_per_img = self.sampling_params['proposals_per_img']

        for ref_view in tqdm(self.ref_views, total=len(self.ref_views)):
            self.logger.info(f'USING REFERENCE VIEW {ref_view}')

            tc1w, Rc1w = get_tR(ref_view, self.image_struct)
            if len(tc1w) == 0:
                self.logger.debug(f'tR not available for img: {ref_view}')
                print(f'tR not available for img: {ref_view}')
                continue

            tc1w *= self.scale
            twc1, Rwc1 = camera_to_world_tR(tc1w, Rc1w)

            bboxes = self.load_pt_file(ref_view)[:proposals_per_img]

            if bboxes is None:
                self.logger.exception(f'Proposal file: {ref_view} not found!!')
                continue

            img_path = os.path.join(self.scene_img_path, ref_view)
            # img = Image.open(img_path).resize(self.image_params['proposal_size'])
            img = Image.open(img_path)
            depth_name = ref_view.split('.')[0][:-1] + '3.png'
            depth_path = os.path.join(self.scene_depth_path, depth_name)
            depth = Image.open(depth_path)

            # ---------------------- SAVE OR PLOT PROPOSALS ------------------------
            if self.plot_params['proposals'] or self.plot_params['save_proposals']:
                fig, ax = bboxplot_in_img(img, bboxes, fontsize=7,
                                          return_fig=True,
                                          linewidth=2)
                plt.title(f'Proposals for {ref_view}')
                if self.plot_params['proposals']:
                    plt.show()

                if self.plot_params['save_proposals']:
                    fig.savefig(os.path.join(self.plot_save_path,
                                             f'proposals_{ref_view.split(".")[0]}.png'),
                                bbox_inches='tight', dpi=300)
                plt.close()
            # -----------------------------------------------------------------------
            x, y, z = generate_flat_xyz(depth)

            bboxes_px_idx = bbox_pixel_indices_list(np.array(bboxes),
                                                    x_flat=x,
                                                    y_flat=y,
                                                    z_flat=z,
                                                    filter_depth=False,
                                                    coordinates=False)

            pcl_cam1, _ = project_xyz_to_camera(x_flat=x, y_flat=y, z_flat=z,
                                                center_x=self.cx_prop, center_y=self.cy_prop,
                                                focal_x=self.fx_prop, focal_y=self.fy_prop)

            neighbors_dict = self.generate_neighbors(view=ref_view)
            sampled_neighbors = self.sample_neighbors(neighbors_dict=neighbors_dict)

            triplet_dict = OrderedDict()

            for sampled_neighbor in sampled_neighbors:
                triplet_dict[sampled_neighbor] = []

                self.logger.info(f'\nCalculating for neighbor {sampled_neighbor}')
                self.reproject_match_bboxes(ref_name=ref_view, ref_img=img, pcl_cam1=pcl_cam1,
                                            ref_bboxes=bboxes, ref_bbox_indices=bboxes_px_idx,
                                            neighbor_name=sampled_neighbor, twc1=twc1,
                                            Rwc1=Rwc1,
                                            output_list=triplet_dict[sampled_neighbor])

            pickle_filename = ref_view.split('.')[0] + '.pickle'
            pickle_path = os.path.join(self.triplet_save_path, pickle_filename)

            with open(pickle_path, 'wb') as f:
                pickle.dump(triplet_dict, f)

        with open(os.path.join(self.output_scene_path, 'time.txt'), 'a') as f:
            f.write("END TIME: " + datetime.now().strftime("%m-%d-%Y_%H:%M:%S") + '\n')
コード例 #2
0
    def reproject_match_bboxes(self, ref_name, ref_img, pcl_cam1, ref_bboxes, ref_bbox_indices,
                               neighbor_name, twc1,
                               Rwc1, output_list):
        """
            Reproject all Camera World pixels of reference image to Neighbor View 2d
            Load Neighbor Proposal bounding boxes
                Skip this neighbor if proposal not available
            For each bounding box in reference image
                If num pixels inside reprojected image < threshold
                    Skip this bounding box
                For each bounding box in neighbor image
                    Calculate iou
                Find max iou
                If max iou < threshold, skip
        """
        tc2w, Rc2w = get_tR(neighbor_name, self.image_struct)

        if len(tc2w) == 0:
            self.logger.debug(f'tR not available for neighbor {neighbor_name}')
            print(f'tR not available for neighbor {neighbor_name}')
            return None

        tc2w *= self.scale
        tc2c1, Rc2c1 = inter_camera_tR(twc1, Rwc1, tc2w, Rc2w)

        pcl_cam21 = np.matmul(Rc2c1, pcl_cam1) + tc2c1
        proj21 = project_camera_to_2d(pcl_cam21, center_x=self.cx_prop, center_y=self.cy_prop,
                                      focal_x=self.fx_prop, focal_y=self.fy_prop)

        neighbor_bboxes = self.load_pt_file(neighbor_name)

        if neighbor_bboxes is None:
            # print(f'File not found maybe because no proposals in image!!')
            self.logger.exception(
                f'Proposal file: {neighbor_name} not found!!')
            return None
        elif len(neighbor_bboxes) == 0:
            self.logger.debug(f'No bbox in {neighbor_name}')
            return None

        neighbor_bboxes = neighbor_bboxes[:self.sampling_params['proposals_per_neighbor_image']]

        neighbor_img_path = os.path.join(self.scene_img_path, neighbor_name)
        # neighbor_img = Image.open(neighbor_img_path).resize(self.image_params['proposal_size'])
        neighbor_img = Image.open(neighbor_img_path)

        for e, bbox_px_idx in enumerate(ref_bbox_indices):
            current_ref_bbox = ref_bboxes[e]

            proj_x = proj21[0][bbox_px_idx]
            proj_y = proj21[1][bbox_px_idx]
            proj_z = pcl_cam21[2][bbox_px_idx]

            inside_image = np.logical_and.reduce(
                (proj_x >= 0, proj_x < self.image_params['proposal_width'],
                 proj_y >= 0, proj_y < self.image_params['proposal_height'],
                 proj_z > 0))

            valid_projected_pxl = np.sum(inside_image)
            # FixMe: Include zero depths in count as well
            total_projected_pxl = len(bbox_px_idx)

            if valid_projected_pxl < self.match_params['min_valid_pixels']:
                # print(f'Skipping valid pixels = {valid_projected_pxl}')
                self.logger.debug(f'Skipping because valid pixels = {valid_projected_pxl}')
                continue

            proj_x = proj_x[inside_image]
            proj_y = proj_y[inside_image]

            matched_pixels_iou = []

            for neighbor_bbox_idx, neighbor_bbox in enumerate(neighbor_bboxes):
                area_bbox = (neighbor_bbox[2] - neighbor_bbox[0]) * (
                        neighbor_bbox[3] - neighbor_bbox[1])
                proj_x_inside_bbox = np.logical_and(
                    proj_x >= neighbor_bbox[0],
                    proj_x <= neighbor_bbox[2])
                proj_y_inside_bbox = np.logical_and(
                    proj_y >= neighbor_bbox[1],
                    proj_y <= neighbor_bbox[3])
                num_inside_pixels = np.sum(
                    np.logical_and(proj_x_inside_bbox, proj_y_inside_bbox))
                matched_pixels_iou.append(num_inside_pixels /
                                          (area_bbox + (total_projected_pxl - num_inside_pixels)))

            # TODO: Random sample for multiple same max_iou
            max_iou_idx = np.argmax(matched_pixels_iou)
            max_iou = matched_pixels_iou[max_iou_idx]
            self.logger.info(f'Max IOU = {max_iou}')

            pos_bbox = neighbor_bboxes[max_iou_idx]

            # PLOT REF AND POS BBOX
            # -------------------------------------------------------------------------
            if self.plot_params['ref_pos'] or self.plot_params['save_ref_pos'] or \
                    self.plot_params['triplet'] or self.plot_params['save_triplet']:

                fig, [ax1, ax2] = plt.subplots(1, 2, figsize=(25, 14))
                ax1.imshow(ref_img)
                ax2.imshow(neighbor_img)

                _ = scatterplot_in_img(neighbor_img, [proj_x, proj_y],
                                       s=2, return_fig=True,
                                       fig=fig,
                                       ax=ax2)
                _ = bboxplot_in_img(neighbor_img,
                                    [pos_bbox],
                                    fig=fig, ax=ax2,
                                    numbering=False,
                                    return_fig=True, linewidth=3)
                _ = bboxplot_in_img(ref_img, [current_ref_bbox],
                                    fig=fig, ax=ax1,
                                    numbering=False,
                                    return_fig=True, linewidth=3
                                    )

                ax1.title.set_text(ref_name)
                ax2.title.set_text(neighbor_name)

                ref_name_raw = ref_name.split(".")[0]
                neighbor_name_raw = neighbor_name.split(".")[0]

                fig.suptitle(f'{ref_name_raw}_{neighbor_name_raw}_{e}\nIOU = {max_iou:.3f}')

                if self.plot_params['ref_pos']:
                    plt.show()

                if self.plot_params['save_ref_pos']:
                    fig.savefig(os.path.join(self.plot_save_path,
                                             f'{ref_name_raw}_{neighbor_name_raw}_{e}.png'),
                                dpi=300)
            # -------------------------------------------------------------------------

            if max_iou < self.match_params['min_pos_iou']:
                self.logger.info(f'No bbox matched in neighbor {neighbor_name} because small IOU')
                continue

            neg_bbox = self.find_negative_bbox(bboxes=ref_bboxes, ref_bbox=current_ref_bbox)

            if neg_bbox is None:
                self.logger.debug(f'Could not find negative bbox!')
                print(f'Could not find negative bbox!')
            else:
                output_list.append([current_ref_bbox, pos_bbox, neg_bbox])

                # PLOT TRIPLET
                # -------------------------------------------------------------------------
                if self.plot_params['triplet'] or self.plot_params['save_triplet']:
                    # print('Triplet')
                    _ = bboxplot_in_img(ref_img,
                                        [neg_bbox],
                                        fig=fig, ax=ax1,
                                        numbering=False, edgecolor='r',
                                        return_fig=True, linewidth=3)

                    fig.suptitle(
                        f'Triplet_{ref_name_raw}_{neighbor_name_raw}_{e}\nIOU = {max_iou:.3f}')

                    if self.plot_params['triplet']:
                        # print('plot triplet')
                        # FixMe: Plot using plt because fig.show doesnt wait to close window
                        fig.show()

                    if self.plot_params['save_triplet']:
                        fig.savefig(os.path.join(self.plot_save_path,
                                                 f'Triplet_{ref_name_raw}_{neighbor_name_raw}_{e}.png'),
                                    dpi=300)

                    plt.close()
                # -------------------------------------------------------------------------

        return None
コード例 #3
0
    def associate(self):
        logger = logging.getLogger(__name__)
        logging.basicConfig(filename=os.path.join('logs',
                                                  f'association_node_{time()}.log'),
                            filemode='w')
        logger.setLevel(logging.DEBUG)

        for zipped, triplet_folder in [[zip(self.train_centers, self.train_nodes,
                            self.train_anchor_views), 'train'], [zip(self.test_centers, self.test_nodes, self.test_anchor_views), 'test']]:

            tqdm_length = len(self.train_nodes)

            if triplet_folder == 'test':
                tqdm_length = len(self.test_nodes)

            for cluster_center, cluster_nodes, anchor_views in tqdm(zipped, total=tqdm_length):

                proposal_filenames = [self.convert_jpg_pt(i) for i in anchor_views]
                proposal_img_filenames = anchor_views

                for proposal_filename, img_filename in zip(proposal_filenames,
                                                           proposal_img_filenames):
                    # print(f'Fetching samples for {img_filename}')
                    logger.info(f'Fetching samples for {img_filename}')
                    # print(f'Fetching samples for {img_filename}')

                    bboxes = self.load_pt_file(proposal_filename)
                    bboxes = bboxes[:self.proposals_per_img]

                    img_folder = self.scene
                    img_struct_folder = self.image_struct_dict[img_folder]
                    img_struct = img_struct_folder['image_struct']
                    img_scale = img_struct_folder['scale']
                    tc1w, Rc1w = get_tR(img_filename, img_struct)

                    if len(tc1w) == 0:
                        logger.debug(f'tR not available for img: {img_filename}')
                        print(f'tR not available for img: {img_filename}')
                        continue

                    tc1w *= img_scale

                    twc1, Rwc1 = camera_to_world_tR(tc1w, Rc1w)

                    img_path = os.path.join(self.dataset_root, img_folder,
                                            'jpg_rgb',
                                            img_filename)
                    img = Image.open(img_path).resize(image_defaults['size'])
                    camera_intrinsics = self.camera_intrinsics[img_folder]

                    if SAVE_FIG or PLOT_FIG:
                        fig, ax = bboxplot_in_img(img, bboxes, fontsize=10,
                                                  return_fig=True,
                                                  linewidth=3)

                    depth_name = self.convert_jpg_depth(img_filename)
                    depth_path = os.path.join(self.dataset_root, img_folder,
                                              'high_res_depth', depth_name)
                    # Scale depth for new image size
                    depth = Image.open(depth_path).resize(image_defaults['size'],
                                                          resample=Image.NEAREST)

                    x, y, z = generate_flat_xyz(depth)
                    cx = camera_intrinsics['cx'] * x_resize_factor
                    cy = camera_intrinsics['cy'] * y_resize_factor
                    fx = camera_intrinsics['fx'] * x_resize_factor
                    fy = camera_intrinsics['fy'] * y_resize_factor

                    pcl_cam1, _ = project_xyz_to_camera(x_flat=x, y_flat=y,
                                                        z_flat=z,
                                                        center_x=cx,
                                                        center_y=cy, focal_x=fx,
                                                        focal_y=fy)

                    neighbor_names = self.sample_neighbor_nodes(node=cluster_center,
                                                                center_nodes=self.train_centers,
                                                                clusters=self.train_nodes)
                    neighbor_img_path = [
                        os.path.join(self.dataset_root, img_folder, 'jpg_rgb',
                                     i) for i in neighbor_names]
                    neighbor_images = [Image.open(i).resize(image_defaults['size'])
                                       for
                                       i in neighbor_img_path]

                    logger.info(f'Sampled Neighbors : {neighbor_names}')
                    # print(f'Sampled Neighbors : {neighbor_names}')

                    bboxes_px_idx = bbox_pixel_indices_list(np.array(bboxes),
                                                            x_flat=x,
                                                            y_flat=y,
                                                            z_flat=z,
                                                            filter_depth=True,
                                                            coordinates=False)

                    if SAVE_FIG or PLOT_FIG:
                        for i in bboxes_px_idx:
                            fig, ax = scatterplot_in_img(img,
                                                         coordinates=(x[i], y[i]),
                                                         s=1,
                                                         fig=fig, ax=ax,
                                                         return_fig=True)

                        if SAVE_FIG:
                            plt.savefig(
                                os.path.join('/mnt/sda2/workspace/triplet_nodes_images',
                                             img_filename.split('.')[0] + '.png'))
                        if PLOT_FIG:
                            plt.show()
                        plt.close()
                    # {Neighbor_name: [[1st triplet], ...]}
                    to_save = OrderedDict()

                    for neighbor_name, neighbor_img in zip(neighbor_names,
                                                           neighbor_images):
                        to_save[neighbor_name] = []

                        # print(f'\nCalculating for neighbor {neighbor_name}')
                        logger.info(f'\nCalculating for neighbor {neighbor_name}')
                        # print(f'\nCalculating for neighbor {neighbor_name}')

                        tc2w, Rc2w = get_tR(neighbor_name, img_struct)

                        if len(tc2w) == 0:
                            logger.debug(
                                f'tR not available for neighbor {neighbor_name}')
                            print(f'tR not available for neighbor {neighbor_name}')
                            continue

                        tc2w *= img_scale
                        tc2c1, Rc2c1 = inter_camera_tR(twc1, Rwc1, tc2w, Rc2w)

                        pcl_cam21 = np.matmul(Rc2c1, pcl_cam1) + tc2c1
                        proj21 = project_camera_to_2d(pcl_cam21, center_x=cx,
                                                      center_y=cy, focal_x=fx,
                                                      focal_y=fy)

                        neighbor_bboxes = self.load_pt_file(
                            self.convert_jpg_pt(neighbor_name))
                        if neighbor_bboxes is None:
                            # print(f'File not found maybe because no proposals in image!!')
                            logger.exception(
                                f'Proposal file: {neighbor_name} not found!!')
                            continue

                        neighbor_bboxes = neighbor_bboxes[
                                          :self.proposals_neighbor_img]
                        # bboxplot_in_img(neighbor_img, neighbor_bboxes)

                        # Iterate over each of input image bbox
                        for e, bbox_px_idx in enumerate(bboxes_px_idx):
                            # Filter pixels outside image
                            # print(f'Bbox # = {e}')
                            logger.debug(f'Bbox # = {e}')

                            proj_x = proj21[0][bbox_px_idx]
                            proj_y = proj21[1][bbox_px_idx]
                            proj_z = pcl_cam21[2][bbox_px_idx]
                            # print(pcl_cam21.shape)
                            # scatterplot_in_img(neighbor_img,
                            #                    coordinates=(proj_x, proj_y),
                            #                    s=2)

                            inside_image = np.logical_and.reduce(
                                (proj_x >= 0, proj_x < image_defaults['width'],
                                 proj_y >= 0, proj_y < image_defaults['height'],
                                 proj_z > 0))

                            # Only for projected pixels with number of pixels>threshold
                            total_projected_pxl = len(bbox_px_idx)
                            valid_projected_pxl = np.sum(inside_image)

                            # TODO: Make this a parameter
                            # Skip if number of valid projected pixels is < threshold
                            if valid_projected_pxl < 15:
                                # print(f'Skipping valid pixels = {valid_projected_pxl}')
                                logger.debug(
                                    f'Skipping valid pixels = {valid_projected_pxl}')
                                continue

                            proj_x = proj_x[inside_image]
                            proj_y = proj_y[inside_image]

                            # print(f'Num pixels = {valid_projected_pxl}')
                            logger.debug(f'Num pixels = {valid_projected_pxl}')

                            matched_pixels_iou = np.zeros(len(neighbor_bboxes))

                            # Iterate over each of SHUFFLED neighbor image bbox
                            neighbor_bbox_indices = np.random.choice(
                                list(range(len(neighbor_bboxes))),
                                size=len(neighbor_bboxes),
                                replace=False)
                            for neighbor_bbox_idx in neighbor_bbox_indices:
                                neighbor_bbox = neighbor_bboxes[neighbor_bbox_idx]

                                area = (neighbor_bbox[2] - neighbor_bbox[0]) * (
                                        neighbor_bbox[3] - neighbor_bbox[1])
                                inside_proj_x = np.logical_and(
                                    proj_x >= neighbor_bbox[0],
                                    proj_x <= neighbor_bbox[2])
                                inside_proj_y = np.logical_and(
                                    proj_y >= neighbor_bbox[1],
                                    proj_y <= neighbor_bbox[3])
                                num_inside = np.sum(
                                    np.logical_and(inside_proj_x, inside_proj_y))
                                # TODO: Note that only using area didn't produce good result because always prioritized smallest box with max pixels inside
                                matched_pixels_iou[neighbor_bbox_idx] = (
                                            num_inside / (
                                            area + (
                                                total_projected_pxl - num_inside)))

                            matched_pixels = np.array(matched_pixels_iou)
                            matched_bbox_idx = matched_pixels.argmax()
                            # print(f'IOU = {matched_pixels[matched_bbox_idx]}')
                            logger.debug(
                                f'IOU = {matched_pixels[matched_bbox_idx]}')

                            # TODO: Make this a parameter
                            if matched_pixels[matched_bbox_idx] < 0.2:
                                logger.debug(f'Skipping because small IOU')
                                # print(f'Skipping because small IOU')
                                continue
                            if SAVE_FIG or PLOT_FIG:
                                fig, [ax2, ax1] = plt.subplots(1, 2,
                                                               figsize=(25, 14))
                                ax1.imshow(neighbor_img)
                                _ = scatterplot_in_img(neighbor_img,
                                                       [proj_x, proj_y],
                                                       s=2, return_fig=True,
                                                       fig=fig,
                                                       ax=ax1)
                                _ = bboxplot_in_img(neighbor_img,
                                                    [neighbor_bboxes[
                                                         matched_bbox_idx]],
                                                    fig=fig, ax=ax1,
                                                    numbering=False,
                                                    return_fig=True, linewidth=3)
                            current_bbox = bboxes[e]

                            found_neg = False

                            # TODO: Make this a parameter
                            max_search_count = min(10, len(bboxes))
                            search_idx_list = list(range(max_search_count))
                            # Shuffle the index list
                            np.random.shuffle(search_idx_list)

                            for neg_bbox_idx in search_idx_list:
                                neg_bbox = bboxes[neg_bbox_idx]

                                intersect_xmin = max(current_bbox[0], neg_bbox[0])
                                intersect_ymin = max(current_bbox[1], neg_bbox[1])
                                intersect_xmax = min(current_bbox[2], neg_bbox[2])
                                intersect_ymax = min(current_bbox[3], neg_bbox[3])
                                intersect_area = (
                                                             intersect_xmax - intersect_xmin) * (
                                                         intersect_ymax - intersect_ymin)
                                union_area = (current_bbox[2] - current_bbox[0]) * (
                                        current_bbox[3] - current_bbox[1]) + (
                                                     neg_bbox[3] - neg_bbox[1]) * (
                                                     neg_bbox[2] - neg_bbox[
                                                 0]) - intersect_area
                                iou = intersect_area / union_area

                                if iou <= self.neg_bbox_iou_thresh:
                                    # print(f'Neg bbox iou = {iou}')
                                    logger.debug(f'Neg bbox iou = {iou}')
                                    found_neg = True
                                    break

                            if not found_neg:
                                logger.debug(
                                    f'Did not find negative sample so skipping!!')
                                continue

                            if SAVE_FIG or PLOT_FIG:
                                ax2.imshow(img)
                                _ = bboxplot_in_img(img, [current_bbox, neg_bbox],
                                                    fig=fig, ax=ax2,
                                                    return_fig=True, linewidth=3)
                                if SAVE_FIG:
                                    fig_path = os.path.join(
                                        '/mnt/sda2/workspace/triplet_nodes_images',
                                        img_filename.split('.')[0] + '_' +
                                        neighbor_name.split('.')[
                                            0] + '_' + str(e) + '.png'
                                        )
                                    plt.savefig(fig_path)
                                if PLOT_FIG:
                                    plt.show()
                                plt.close()
                            to_save[neighbor_name].append(
                                [current_bbox, neighbor_bboxes[matched_bbox_idx],
                                 neg_bbox])

                    pickle_filename = proposal_filename.split('.')[0] + '.pickle'
                    pickle_path = os.path.join(self.triplet_root, triplet_folder, pickle_filename)

                    with open(pickle_path, 'wb') as f:
                        pickle.dump(to_save, f)