Example #1
0
def plane_detection(color_image, depth_array, loop=1):
    planes_mask, planes_normal, list_plane_params = test_PlaneDetector_send(\
            img_color=color_image, img_depth=depth_array)
    for idx in range(loop - 1):
        planes_mask_x, planes_normal_x, list_plane_params_x = test_PlaneDetector_send(\
            img_color=color_image, img_depth=depth_array)
        planes_mask += planes_mask_x
    planes_mask_binary = planes_mask
    r1, g1, b1 = 255, 0, 40  # Original value
    r2, g2, b2 = 1, 1, 1  # Value that we want to replace it with
    red, green, blue = planes_mask[:, :, 0], planes_mask[:, :,
                                                         1], planes_mask[:, :,
                                                                         2]
    mask = (red > r1) & (green == g1) & (blue > b1)
    planes_mask_binary[:, :, :3][mask] = [r2, g2, b2]
    planes_mask_binary = planes_mask_binary[:, :, 0]
    # plane is blue (255,0,40)
    return planes_mask_binary
Example #2
0
def main():

    # Create a pipeline
    pipeline = rs.pipeline()

    #Create a config and configure the pipeline to stream
    #  different resolutions of color and depth streams
    config = rs.config()

    rs.config.enable_device_from_file(config, args.input)

    # Start streaming
    profile = pipeline.start(config)
    depth_sensor = profile.get_device().first_depth_sensor()

    # Create an align object
    # rs.align allows us to perform alignment of depth frames to others frames
    # The "align_to" is the stream type to which we plan to align depth frames.
    align_to = rs.stream.color
    align = rs.align(align_to)

    vis = x3d.visualization.Visualizer()
    vis.create_window()

    # ocgd = x3d.geometry.OccupancyGrid(0.05, 512)
    ocgd = x3d.geometry.OccupancyGrid()
    ocgd.visualize_free_area = False
    flip_transform = [[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]
    prev_rgbd_image = None
    option = x3d.odometry.OdometryOption()
    cur_trans = np.identity(4)

    # Streaming loop
    frame_count = 0
    try:
        while True:

            dt0 = datetime.now()

            # Get frameset of color and depth
            frames = pipeline.wait_for_frames()

            # Align the depth frame to color frame
            aligned_frames = align.process(frames)

            # Get aligned frames
            aligned_depth_frame = aligned_frames.get_depth_frame()
            aligned_depth_frame = depth_filter(aligned_depth_frame)
            color_frame = aligned_frames.get_color_frame()
            intrinsic = x3d.camera.PinholeCameraIntrinsic(
                get_intrinsic_matrix(color_frame))

            # Validate that both frames are valid
            if not aligned_depth_frame or not color_frame:
                continue

            depth_temp = np.array(aligned_depth_frame.get_data())
            color_temp = np.asarray(color_frame.get_data())

            ############ Plane Detection
            ## need to add smoothening between frames - by plane weights' variance?
            try:
                ### need to add multithreading here (and maybe other methods?)
                planes_mask_binary = plane_detection(color_temp, depth_temp,\
                    loop=3)
            except TypeError as e:
                try:
                    print("plane mask 1st error")
                    planes_mask, planes_normal, list_plane_params = test_PlaneDetector_send(
                        img_color=color_temp, img_depth=depth_temp)
                except TypeError as e:
                    print("plane mask not detected-skipping frame")
                    continue
            ##############################################
            ## Hole filling for plane_mask (plane mask isn't binary - fixed that!)
            planes_mask_binary = nd.binary_fill_holes(planes_mask_binary)
            planes_mask_binary = planes_mask_binary.astype(np.uint8)
            # Clean plane mask object detection by seg_mask
            planes_mask_binary_3d = np.dstack(
                (planes_mask_binary, planes_mask_binary, planes_mask_binary))
            #############################################

            depth_image = x3d.geometry.Image(depth_temp * planes_mask_binary)
            color_image = x3d.geometry.Image(color_temp *
                                             planes_mask_binary_3d)

            rgbd_image = x3d.geometry.RGBDImage.create_from_color_and_depth(
                color_image, depth_image)
            if not prev_rgbd_image is None:
                res, odo_trans, _ = x3d.odometry.compute_rgbd_odometry(
                    prev_rgbd_image, rgbd_image, intrinsic, np.identity(4),
                    x3d.odometry.RGBDOdometryJacobianFromHybridTerm(), option)
                if res:
                    cur_trans = np.matmul(cur_trans, odo_trans)

            prev_rgbd_image = rgbd_image
            temp = x3d.geometry.PointCloud.create_from_rgbd_image(
                rgbd_image, intrinsic)
            temp.transform(np.matmul(cur_trans, flip_transform))
            temp = temp.voxel_down_sample(0.05)
            ocgd.insert(temp, cur_trans[:3, 3])

            if frame_count == 0:
                vis.add_geometry(ocgd)

            vis.update_geometry(ocgd)
            vis.poll_events()
            vis.update_renderer()

            dt1 = datetime.now()
            process_time = dt1 - dt0
            print("FPS: " + str(1 / process_time.total_seconds()))
            frame_count += 1

    finally:
        pipeline.stop()
    vis.destroy_window()
Example #3
0
def run_loop(bag_path, seg_model, seg_opts, save_images=False, output_mode=0):
    if save_images:
        create_folders()
    # Create pipeline
    pipeline = rs.pipeline()
    # Create a config object
    config = rs.config()
    # Tell config that we will use a recorded device from filem to be used by the pipeline through playback.
    rs.config.enable_device_from_file(config, args.input)
    # Start streaming from file
    Pipe = pipeline.start(config)

    # Getting the depth sensor's depth scale (see rs-align example for explanation)
    depth_sensor = Pipe.get_device().first_depth_sensor()
    depth_scale = depth_sensor.get_depth_scale()
    print("Depth Scale is: ", depth_scale)  # can be commented out

    if output_mode == 0 or output_mode == 1:
        # Create opencv window to render image in
        cv2.namedWindow("Full Stream", cv2.WINDOW_NORMAL)

    flip_transform = [[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]

    # Create colorizer object
    colorizer = rs.colorizer()
    idx = 0
    # initial frame delay
    idx_limit = 30

    # pre_seg_mask_sum = None  # previous frame path segmentation area - isn't being used right now

    # Streaming loop
    try:
        while True:
            idx += 1
            # Get frameset of depth
            frames = pipeline.wait_for_frames()
            # ignore first idx frames
            if idx < idx_limit:
                continue
            else:
                pass

            align = rs.align(rs.stream.color)
            frames = align.process(frames)

            # Get color frame
            color_frame = frames.get_color_frame()
            # Get intrinsic in Open3d format for mode 2 and 3 for point cloud output
            if output_mode == 1 or output_mode == 2:
                intrinsic = o3d.camera.PinholeCameraIntrinsic(
                    get_intrinsic_matrix(color_frame))
            # Get depth frame
            depth_frame = frames.get_depth_frame()
            # Print intrinsics and extrinsics - not necessary : can be commented out
            if idx == idx_limit:
                camera_intrinsics(color_frame, depth_frame, Pipe)

            color_image = np.asanyarray(color_frame.get_data())

            ### Add SEGMENTATION part here ###
            pred = test(color_image, seg_model, seg_opts)

            # pavement, floor, road, earth/ground, field, path, dirt/track - chosen classes for the model selected (we'd like an oversegmentation of the path)
            seg_mask = (pred == 11) | (pred == 3) | (pred == 6) | (
                pred == 13) | (pred == 29) | (pred == 52) | (
                    pred == 91)  #.astype(np.uint8)

            if idx == idx_limit:  # 1st frame detection needs to be robust
                pre_seg_mask_sum = np.sum(seg_mask)
            # checking for bad detection
            new_seg_sum = np.sum(seg_mask)
            diff = abs(new_seg_sum - pre_seg_mask_sum)
            # if diff > pre_seg_mask_sum/15:  # smoothening between segmentation outputs - seems like a bad idea since the model inputs are not connected between timesteps
            #     seg_mask = np.ones_like(pred).astype(np.uint8) # need to add depth (5mt) criterea for calculation for robustness
            #     del new_seg_sum
            # else:
            pre_seg_mask_sum = new_seg_sum
            ### mask Hole filling
            seg_mask = nd.binary_fill_holes(seg_mask).astype(int)
            seg_mask = seg_mask.astype(np.uint8)
            #####
            seg_mask_3d = np.dstack((seg_mask, seg_mask, seg_mask))

            pred_color = colorEncode(
                pred,
                loadmat(os.path.join(model_folder, 'color150.mat'))['colors'])
            ##################################

            depth_frame = depth_filter(depth_frame)
            depth_array = np.asarray(depth_frame.get_data())
            # Colorize depth frame to jet colormap
            depth_color_frame = colorizer.colorize(depth_frame)
            # Convert depth_frame to numpy array to render image in opencv
            depth_color_image = np.asanyarray(depth_color_frame.get_data())

            ############ Plane Detection
            ## need to add smoothening between frames - by plane weights' variance?
            try:
                ### need to add multithreading here (and maybe other methods?)
                planes_mask_binary = plane_detection(color_image*seg_mask_3d, depth_array*seg_mask,\
                    loop=5)
            except TypeError as e:
                try:
                    print("plane mask 1st error")
                    planes_mask, planes_normal, list_plane_params = test_PlaneDetector_send(
                        img_color=color_image * seg_mask_3d,
                        img_depth=depth_array * seg_mask)
                except TypeError as e:
                    print("plane mask not detected-skipping frame")
                    continue
                    ## removed this part
                    planes_mask = np.ones_like(depth_array).astype(np.uint8)
                    planes_mask = np.dstack(
                        (planes_mask, planes_mask, planes_mask))
            ##############################################
            ## Hole filling for plane_mask (plane mask isn't binary - fixed that!)
            planes_mask_binary = nd.binary_fill_holes(planes_mask_binary)
            planes_mask_binary = planes_mask_binary.astype(np.uint8)
            # Clean plane mask object detection by seg_mask
            planes_mask_binary *= seg_mask
            planes_mask_binary_3d = np.dstack(
                (planes_mask_binary, planes_mask_binary, planes_mask_binary))

            edges = planes_mask_binary - nd.morphology.binary_dilation(
                planes_mask_binary
            )  # edges calculation - between travesable and non-traversable path
            #############################################

            if output_mode == 1 or output_mode == 2:
                odepth_image = o3d.geometry.Image(depth_array * edges)
                ocolor_image = o3d.geometry.Image(color_image * np.dstack(
                    (edges, edges, edges)))

                rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
                    ocolor_image,
                    odepth_image,
                    depth_scale=1.0 / depth_scale,
                    depth_trunc=10,  # set to 10 metres
                    convert_rgb_to_intensity=False)
                temp = o3d.geometry.PointCloud.create_from_rgbd_image(
                    rgbd_image, intrinsic)
                temp.transform(flip_transform)
                # temp = temp.voxel_down_sample(0.03)

            # Point cloud output of frame is appended to the list
            if output_mode == 1 or output_mode == 2:
                output_list.append(temp)

            # image format conversion for cv2 visualization/output
            if output_mode == 0 or output_mode == 1 or save_images == True:
                pred_color = cv2.cvtColor(pred_color, cv2.COLOR_RGB2BGR)
                color_image = cv2.cvtColor(color_image, cv2.COLOR_RGB2BGR)
                edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
                ## for displaying seg_mask
                seg_mask = (np.array(seg_mask) * 255).astype(np.uint8)
                seg_mask = cv2.cvtColor(
                    seg_mask, cv2.COLOR_GRAY2BGR)  # segmentation binary mask
                final_output_mask = cv2.cvtColor(
                    planes_mask_binary,
                    cv2.COLOR_GRAY2BGR)  # final traversable path mask

            if output_mode == 0 or output_mode == 1:
                # # Blending rgb and depth images for display - can check alignment with this as well
                alpha = 0.2
                beta = (1.0 - alpha)
                dst = cv2.addWeighted(
                    color_image, alpha, pred_color, beta, 0.0
                )  # color and segmentation output from ADE20K model blended
                dst2 = cv2.addWeighted(depth_color_image, alpha, color_image,
                                       beta,
                                       0.0)  # color and depth blended together
                ##################################

                ### delete later if needed - color image masked by final traversable path
                final_output = color_image * planes_mask_binary_3d
                mask = (final_output[:, :, 0] == 0) & (
                    final_output[:, :, 1] == 0) & (final_output[:, :, 2] == 0)
                final_output[:, :, :3][mask] = [255, 255, 255]
                ######

                ### Select outputs for visualization - we've chosen some as default
                image_set1 = np.vstack((dst, dst2))
                # image_set2 = np.vstack((planes_mask_binary_3d*255, seg_mask))
                # image_set2 = np.vstack((dst, final_output))
                image_set2 = np.vstack((edges, final_output))
                ### Choose which images you want to display from above
                combined_images = np.concatenate((image_set1, image_set2),
                                                 axis=1)

            if save_images == True:
                # Outputs saved - you can modify this
                cv2.imwrite("output/visualization/frame%d.png" % idx,
                            combined_images)
                cv2.imwrite("data/color/frame%d.png" % idx,
                            color_image)  # save frame as JPEG file
                cv2.imwrite("data/depth/frame%d.png" % idx,
                            depth_array)  # save frame as JPEG file
                cv2.imwrite("output/edges/frame%d.png" % idx,
                            edges)  # save frame as JPEG file
                cv2.imwrite("output/segmentation_mask/frame%d.png" % idx,
                            seg_mask)  # save frame as JPEG file
                cv2.imwrite("output/output_mask/frame%d.png" % idx,
                            final_output_mask)  # save frame as JPEG file

            if output_mode == 0 or output_mode == 1:
                try:
                    cv2.imshow('Full Stream', combined_images)
                except TypeError as e:
                    print(idx, e)
                key = cv2.waitKey(1)
                # if pressed escape exit program
                if key == 27:
                    cv2.destroyAllWindows()
                    break
    finally:
        pipeline.stop()
        if output_mode == 0 or output_mode == 1:
            cv2.destroyAllWindows()
    return
Example #4
0
def run_loop(bag_path, seg_model, seg_opts, save_images=False):
    # Create pipeline
    pipeline = rs.pipeline()
    # Create a config object
    config = rs.config()
    # Tell config that we will use a recorded device from filem to be used by the pipeline through playback.
    rs.config.enable_device_from_file(config, args.input)
    # Start streaming from file
    Pipe = pipeline.start(config)

    # Getting the depth sensor's depth scale (see rs-align example for explanation)
    depth_sensor = Pipe.get_device().first_depth_sensor()
    depth_scale = depth_sensor.get_depth_scale()
    print("Depth Scale is: ", depth_scale)

    # Create opencv window to render image in
    cv2.namedWindow("Full Stream", cv2.WINDOW_NORMAL)

    # Create colorizer object
    colorizer = rs.colorizer()
    idx = 0
    # initial frame delay
    idx_limit = 30

    pre_seg_mask_sum = None  # previous frame path segmentation area

    # Streaming loop
    try:
        while True:
            idx += 1
            # Get frameset of depth
            frames = pipeline.wait_for_frames()
            # ignore first idx frames
            if idx < idx_limit:
                continue
            else:
                pass

            align = rs.align(rs.stream.color)
            frames = align.process(frames)

            # Get color frame
            color_frame = frames.get_color_frame()
            # Get depth frame
            depth_frame = frames.get_depth_frame()
            # Get intrinsics and extrinsics
            if idx == idx_limit:
                camera_intrinsics(color_frame, depth_frame, Pipe)

            color_image = np.asanyarray(color_frame.get_data())

            ### Add Segmentation part here ###
            pred = test(color_image, seg_model, seg_opts)

            # pavement, floor, road, earth/ground, field, path, dirt/track
            seg_mask = (pred == 11) | (pred == 3) | (pred == 6) | (
                pred == 13) | (pred == 29) | (pred == 52) | (
                    pred == 91)  #.astype(np.uint8)

            if idx == idx_limit:  # 1st frame detection needs to be robust
                pre_seg_mask_sum = np.sum(seg_mask)
            # checking for bad detection
            new_seg_sum = np.sum(seg_mask)
            diff = abs(new_seg_sum - pre_seg_mask_sum)
            # if diff > pre_seg_mask_sum/15:  # smoothening between segmentation outputs - seems like a bad idea since the model inputs are not connected between timesteps
            #     seg_mask = np.ones_like(pred).astype(np.uint8) # need to add depth (5mt) criterea for calculation for robustness
            #     del new_seg_sum
            # else:
            pre_seg_mask_sum = new_seg_sum
            ### mask Hole filling
            seg_mask = nd.binary_fill_holes(seg_mask).astype(int)
            seg_mask = seg_mask.astype(np.uint8)
            #####
            seg_mask_3d = np.dstack((seg_mask, seg_mask, seg_mask))

            pred_color = colorEncode(
                pred,
                loadmat(os.path.join(model_folder, 'color150.mat'))['colors'])
            ##################################

            depth_frame = depth_filter(depth_frame)
            depth_array = np.asarray(depth_frame.get_data())
            # Colorize depth frame to jet colormap
            depth_color_frame = colorizer.colorize(depth_frame)
            # Convert depth_frame to numpy array to render image in opencv
            depth_color_image = np.asanyarray(depth_color_frame.get_data())

            ############ Plane Detection
            ## need to add smoothening between frames - by plane weights' variance?
            try:
                ### need to add multithreading here (and maybe other methods?)
                planes_mask_binary = plane_detection(color_image*seg_mask_3d, depth_array*seg_mask,\
                    loop=5)
            except TypeError as e:
                try:
                    print("plane mask 1st error")
                    planes_mask, planes_normal, list_plane_params = test_PlaneDetector_send(
                        img_color=color_image * seg_mask_3d,
                        img_depth=depth_array * seg_mask)
                except TypeError as e:
                    print("plane mask not detected-skipping frame")
                    continue
                    ## removed this part
                    planes_mask = np.ones_like(depth_array).astype(np.uint8)
                    planes_mask = np.dstack(
                        (planes_mask, planes_mask, planes_mask))
            ##############################################
            ## Hole filling for plane_mask (plane mask isn't binary - fixed that!)
            planes_mask_binary = nd.binary_fill_holes(planes_mask_binary)
            planes_mask_binary = planes_mask_binary.astype(np.uint8)
            # Clean plane mask object detection by seg_mask
            planes_mask_binary *= seg_mask
            planes_mask_binary_3d = np.dstack(
                (planes_mask_binary, planes_mask_binary, planes_mask_binary))
            edges = planes_mask_binary - nd.morphology.binary_dilation(
                planes_mask_binary)  # edges calculation
            edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
            #############################################

            # for cv2 output
            pred_color = cv2.cvtColor(pred_color, cv2.COLOR_RGB2BGR)
            color_image = cv2.cvtColor(color_image, cv2.COLOR_RGB2BGR)

            # if save_images == True:
            #     cv2.imwrite("data_/color/frame%d.png" % idx, color_image)     # save frame as JPEG file
            #     cv2.imwrite("data_/depth/frame%d.png" % idx, depth_array)     # save frame as JPEG file
            #     cv2.imwrite("data_/color_depth/frame%d.png" % idx, depth_color_image)     # save frame as JPEG file
            #     cv2.imwrite("data_/thresholded_color/frame%d.png" % idx, thresholded_color_image)     # save frame as JPEG file
            #     # cv2.imwrite("data_/thresholded_depth/frame%d.png" % idx, thresholded_depth_image)     # save frame as JPEG file

            # # Blending images
            alpha = 0.2
            beta = (1.0 - alpha)
            dst = cv2.addWeighted(color_image, alpha, pred_color, beta, 0.0)
            # kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
            # res = cv2.morphologyEx(planes_mask,cv2.MORPH_OPEN,kernel)
            dst2 = cv2.addWeighted(depth_color_image, alpha, color_image, beta,
                                   0.0)

            ## for displaying seg_mask
            seg_mask = (np.array(seg_mask) * 255).astype(np.uint8)
            seg_mask = cv2.cvtColor(seg_mask, cv2.COLOR_GRAY2BGR)
            ##################################

            ### delete later
            final_output = color_image * planes_mask_binary_3d
            mask = (final_output[:, :, 0] == 0) & (
                final_output[:, :, 1] == 0) & (final_output[:, :, 2] == 0)
            final_output[:, :, :3][mask] = [255, 255, 255]
            ######

            # if np.sum(planes_mask) == depth_array.shape[0]*depth_array.shape[1]:
            #     image_set1 = np.vstack((dst, color_image))
            # else:
            image_set1 = np.vstack((color_image, depth_color_image))
            # image_set2 = np.vstack((planes_mask_binary_3d*255, seg_mask))
            image_set2 = np.vstack((dst, final_output))
            # image_set2 = np.vstack((edges, final_output))
            combined_images = np.concatenate((image_set1, image_set2), axis=1)
            if save_images == True:
                cv2.imwrite("./meeting_example/frame%d.png" % idx,
                            combined_images)
            try:
                cv2.imshow('Full Stream', combined_images)
            except TypeError as e:
                print(idx, e)
            key = cv2.waitKey(1)
            # if pressed escape exit program
            if key == 27:
                cv2.destroyAllWindows()
                break
    finally:
        pipeline.stop()
        cv2.destroyAllWindows()
    # if save_images == True:
    #     pkl.dump( threshold_mask, open( "data_/depth_threshold.pkl", "wb" ) )
    #     print("Mask pickle saved")
    return
Example #5
0
def run_loop(bag_path, seg_model, seg_opts):
    # Create pipeline
    pipeline = rs.pipeline()
    # Create a config object
    config = rs.config()
    # Tell config that we will use a recorded device from filem to be used by the pipeline through playback.
    rs.config.enable_device_from_file(config, args.input)
    # Start streaming from file
    Pipe = pipeline.start(config)

    # Getting the depth sensor's depth scale (see rs-align example for explanation)
    depth_sensor = Pipe.get_device().first_depth_sensor()
    depth_scale = depth_sensor.get_depth_scale()
    print("Depth Scale is: ", depth_scale)

    # Create colorizer object
    colorizer = rs.colorizer()
    idx = 0
    # initial frame delay
    idx_limit = 30

    vis = x3d.visualization.Visualizer()
    vis.create_window()

    ocgd = x3d.geometry.OccupancyGrid(0.03, 512)
    flip_transform = [[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]

    # pre_seg_mask_sum = None  # previous frame path segmentation area

    # Streaming loop
    frame_count = 0
    try:
        while True:
            idx += 1
            # Get frameset of depth
            frames = pipeline.wait_for_frames()
            # ignore first idx frames
            if idx < idx_limit:
                continue
            else:
                pass

            align = rs.align(rs.stream.color)
            frames = align.process(frames)

            # Get color frame
            color_frame = frames.get_color_frame()
            # Get depth frame
            depth_frame = frames.get_depth_frame()
            # Get intrinsics and extrinsics

            if idx == idx_limit:
                camera_intrinsics(color_frame, depth_frame, Pipe)
            # intrinsic = x3d.camera.PinholeCameraIntrinsic(get_intrinsic_matrix(color_frame))
            intrinsics = color_frame.profile.as_video_stream_profile(
            ).intrinsics
            # color_intrin = color_frame.profile.as_video_stream_profile().intrinsics
            # intrinsic = x3d.camera.PinholeCameraIntrinsic((color_intrin))
            intrinsic = x3d.camera.PinholeCameraIntrinsic(
                640, 480, intrinsics.fx, intrinsics.fy, intrinsics.ppx,
                intrinsics.ppy)

            color_image = np.asanyarray(color_frame.get_data())

            ### Add Segmentation part here ###
            pred = test(color_image, seg_model, seg_opts)

            # pavement, floor, road, earth/ground, field, path, dirt/track
            seg_mask = (pred == 11) | (pred == 3) | (pred == 6) | (
                pred == 13) | (pred == 29) | (pred == 52) | (
                    pred == 91)  #.astype(np.uint8)
            # seg_mask = np.ones((color_image.shape[0], color_image.shape[1]))

            # if idx == idx_limit: # 1st frame detection needs to be robust
            #     pre_seg_mask_sum = np.sum(seg_mask)
            # checking for bad detection
            # new_seg_sum = np.sum(seg_mask)
            # diff = abs(new_seg_sum-pre_seg_mask_sum)
            # if diff > pre_seg_mask_sum/15:  # smoothening between segmentation outputs - seems like a bad idea since the model inputs are not connected between timesteps
            #     seg_mask = np.ones_like(pred).astype(np.uint8) # need to add depth (5mt) criterea for calculation for robustness
            #     del new_seg_sum
            # else:
            # pre_seg_mask_sum = new_seg_sum

            ### mask Hole filling
            seg_mask = nd.binary_fill_holes(seg_mask).astype(int)
            seg_mask = seg_mask.astype(np.uint8)
            #####
            seg_mask_3d = np.dstack((seg_mask, seg_mask, seg_mask))

            # pred_color = colorEncode(pred, loadmat(os.path.join(model_folder, 'color150.mat'))['colors'])
            ##################################

            depth_frame = depth_filter(depth_frame)
            depth_array = np.asarray(depth_frame.get_data())
            # Colorize depth frame to jet colormap
            depth_color_frame = colorizer.colorize(depth_frame)
            # Convert depth_frame to numpy array to render image in opencv
            depth_color_image = np.asanyarray(depth_color_frame.get_data())

            ############ Plane Detection
            ## need to add smoothening between frames - by plane weights' variance?
            try:
                ### need to add multithreading here (and maybe other methods?)
                planes_mask_binary = plane_detection(color_image*seg_mask_3d, depth_array*seg_mask,\
                    loop=3)
            except TypeError as e:
                try:
                    print("plane mask 1st error")
                    planes_mask, planes_normal, list_plane_params = test_PlaneDetector_send(
                        img_color=color_image * seg_mask_3d,
                        img_depth=depth_array * seg_mask)
                except TypeError as e:
                    print("plane mask not detected-need to skip frames")
            ##############################################
            ## Hole filling for plane_mask (plane mask isn't binary - fixed that!)
            planes_mask_binary = nd.binary_fill_holes(planes_mask_binary)
            planes_mask_binary = planes_mask_binary.astype(np.uint8)
            # Clean plane mask object detection by seg_mask
            planes_mask_binary *= seg_mask
            planes_mask_binary_3d = np.dstack(
                (planes_mask_binary, planes_mask_binary, planes_mask_binary))
            #############################################

            depth_image = x3d.geometry.Image(depth_array * planes_mask_binary)
            color_image = x3d.geometry.Image(color_image *
                                             planes_mask_binary_3d)

            rgbd_image = x3d.geometry.RGBDImage.create_from_color_and_depth(
                color_image,
                depth_image,
                depth_scale=1.0 / depth_scale,
                depth_trunc=10,
                convert_rgb_to_intensity=False)
            temp = x3d.geometry.PointCloud.create_from_rgbd_image(
                rgbd_image, intrinsic)
            temp.transform(flip_transform)
            temp = temp.voxel_down_sample(0.03)
            ocgd.insert(temp, np.zeros(3))

            if frame_count == 0:
                vis.add_geometry(ocgd)

            vis.update_geometry(ocgd)
            vis.poll_events()
            vis.update_renderer()

            # dt1 = datetime.now()
            # process_time = dt1 - dt0
            # print("FPS: " + str(1 / process_time.total_seconds()))
            frame_count += 1

    finally:
        pipeline.stop()
        vis.destroy_window()
    return