IntelRealSense / librealsense

Intel® RealSense™ SDK
https://www.intelrealsense.com/
Apache License 2.0
7.62k stars 4.83k forks source link

Pointcloud, how remove background? #8170

Closed RarDay closed 3 years ago

RarDay commented 3 years ago

I get pointcloud from my depth camera. And I want to remove extra points that are far away, how do I put a condition in the code?

Required Info  
Camera Model D435i
Operating System & Version Windows 10
Language Python 3.7

My code for save pointcloud:

import pyrealsense2 as rs

pipe = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth)
pipe.start(config)
colorizer = rs.colorizer()

try:

    frames = pipe.wait_for_frames()
    colorized = colorizer.process(frames)

    ply = rs.save_to_ply("1.ply")
    ply.set_option(rs.save_to_ply.option_ply_binary, False)
    ply.set_option(rs.save_to_ply.option_ply_normals, True)

    print("Saving to 1.ply...")
    ply.process(colorized)
    print("Done")
finally:
    pipe.stop()

And i have code to remove background:

import pyrealsense2 as rs
import numpy as np
import cv2

pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
pipeline.start(config)

align_to = rs.stream.color
align = rs.align(align_to)

try:
    while True:

        frames = pipeline.wait_for_frames()
        aligned_frames = align.process(frames)

        aligned_depth_frame = aligned_frames.get_depth_frame()
        color_frame = aligned_frames.get_color_frame()

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

        depth_image_3d = np.dstack((depth_image, depth_image, depth_image))
        bg_removed = np.where((depth_image_3d > 0.5 / 0.0007) | (depth_image_3d <= 0), 155, color_image)

        cv2.imshow('Align Example', depth_image_3d)

        key = cv2.waitKey(1)

        if key & 0xFF == ord('q') or key == 27:
            cv2.destroyAllWindows()
            break

finally:
    pipeline.stop()
MartyG-RealSense commented 3 years ago

Hi @RarDay You can apply a Threshold Filter to set a minimum and maximum depth distance. Data outside of the defined range is excluded from the image. The threshold filter's programming reference for pyrealsense2 is linked to below.

https://intelrealsense.github.io/librealsense/python_docs/_generated/pyrealsense2.threshold_filter.html

RarDay commented 3 years ago

@MartyG-RealSense hmm yes, i find this func but i dont understand where i must put it

<...>
thre = rs.threshold_filter(0.1, 0.7)

try:
    frames = pipe.wait_for_frames()
    aligned_frames = align.process(frames)
    colorized = colorizer.process(aligned_frames)

    ply = rs.save_to_ply("1.ply")

    ply.set_option(rs.save_to_ply.option_ply_threshold, True)
    ply.process(colorized)
<...>
MartyG-RealSense commented 3 years ago

The above script reference about threshold refers to the export of point cloud data to a ply file.

There is very little information available in regard to scripting for implementing a minimum-maximum depth threshold filter in a Python program. The best guidance that I found is in the link below:

https://github.com/IntelRealSense/librealsense/issues/3002#issuecomment-473044109

acbuynak commented 3 years ago

Hello! I'm interested in a similar application of threshold_filter and wanted to share my progress. Note: I had stumbled across option_range, but was unable to implement.

The below application successfully filtered the point cloud to under the configured distance option (1). The units seem to be in meters. I don't know what defines this, but assume it ties back to option.depth_units. Further, the filter would only accept the frames type and not a frames.get_depth_frame() type. I'm still new to rs and cannot explain why.

pc = rs.pointcloud()
points = rs.points()
pipe = rs.pipeline()

config = rs.config()
config.enable_stream(rs.stream.depth)

pipe.start(config)

threshold_filter = rs.threshold_filter()
threshold_filter.set_option(rs.option.max_distance, 1)

try:
  frames = pipe.wait_for_frames()
  frames_filtered = threshold_filter.process(frames)
RarDay commented 3 years ago

@acbuynak It's that i found, thanks! If you are interested, I want to take the points of the face and record them in the database to then recognize people. Something like "face recognition". image

MartyG-RealSense commented 3 years ago

Thanks so much @acbuynak for sharing your code :)

iPsych commented 2 years ago

@acbuynak It's that i found, thanks! If you are interested, I want to take the points of the face and record them in the database to then recognize people. Something like "face recognition". image

Hi, did you succeed to remove background and save recorded data (in my case, it's .bag, but can be easily converted to .ply)?