Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record 3D image in bag file - several minutes period #3671

Closed
SamConti opened this issue Apr 3, 2019 · 12 comments
Closed

Record 3D image in bag file - several minutes period #3671

SamConti opened this issue Apr 3, 2019 · 12 comments

Comments

@SamConti
Copy link

SamConti commented Apr 3, 2019

  • Before opening a new issue, we wanted to provide you with some useful suggestions (Click "Preview" above for a better view):

  • All users are welcomed to report bugs, ask questions, suggest or request enhancements and generally feel free to open new issue, even if they haven't followed any of the suggestions above :)


Required Info
Camera Model D435
Operating System & Version Ubuntu 16
Kernel Version (Linux Only) 4.4.38
Platform Raspberry Pi
Language python

Issue Description

Hello,

I would like to take a 3D image every 5 minutes and store it in a bag file but I don't know how to do this.
The frame format have to be 1280x720 and Z16 format.

At this point I'm able create the basic :
import pyrealsense2 as rs
pipelne = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 6)
pipeline.start(config)

I think I configure with a frame rate of 6 fps...maybe can I set to 1fps and save an image every 300 images ?
About place the image in bag file, I don't know how to do this...

Thanks,

@dorodnic
Copy link
Contributor

dorodnic commented Apr 4, 2019

Hi @SamConti

Several ways to go about it.

The easiest approach is just to create a pipeline, start, stop, delete the pipeline, wait 5 minutes, repeat.
Drawback is warm-up time of ~0.5-1 second. Benefit is low power consumption since the camera is off most of the time.

Second approach is to use record.pause method.

auto dev = pipe.start(config).get_device().as<rs2::record>();
while (auto fs = pipe.wait_for_frames())
{
     dev.pause();
     sleep(5000);
     dev.resume();
}

Benefits are fast response and one single recorded BAG file (unlike other methods)

There is another tool that can be useful for your needs:
If you explicitly include rs_export.hpp you would be able to save each individual frameset into its own tiny ROS-bag.
This is not as well tested as the main recorder, but these should successfully capture all the data including relevant extrinsic / intrinsic calibration, and you should be able to open them in the Viewer.

#include <librealsense2/rs.hpp>
#include <librealsense2/rs_export.hpp>

rs2::save_single_frameset saver;
while (auto fs = pipe.wait_for_frames())
{
     saver.process(fs);
     sleep(5000);
}

@SamConti
Copy link
Author

SamConti commented Apr 4, 2019

Hello,

Thank you for your feedback.
Clearly I need a bag file for each frame, so first method you explains I think.
But, my apologizes I'm newbie with this camera, how to save the image in bag file ?

I can found this kind of code:

frames = pipeline.wait_for_frames()
depth_frame = frames.get_depth_frame()
depth_image = np.asanyarray(depth_frame.get_data())
cv2.imwrite(args.directory + "/" + str(i).zfill(6) + ".png", depth_image)

I see the code wait for a frame and save it as image but how in bag file ?

@dorodnic
Copy link
Contributor

dorodnic commented Apr 4, 2019

No worries,

int i = 0;
while (true)
{
     { // new scope to force pipeline to be released at the end
           rs2::pipeline p;
           rs2::config cfg;
           std::stringstream ss;
           ss << "file_" << i << ".bag";
           cfg.enable_record_to_file(ss.str());
           p.start(cfg);
           p.wait_for_frames();
           p.stop();
     }
     sleep(5000);
     i++;
}

Check out examples/record-playback for more info

@SamConti
Copy link
Author

SamConti commented Apr 4, 2019

OK I create the bag file in python, but I have a problem with it.
When I load it in Realsense viewer I have this error

Failed to load file C:\Users\Samuel CONTI\Desktop\BagFile.bag. Reason: Io in rs2_context_add_device(ctx:0000021724F39240, file:C): Failed to create ros reader: Bag unindexed

Is there a way to fix this ?

My code is is simply:

import pyrealsense2 as rs
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 6)
config.enable_record_to_file("BagFile.bag")
pipeline.start(config)
frames = pipeline.wait_for_frames()
pipeline.stop()

EDIT: I found the problem, the script have to be closed from the IDE and bag file are correct.

Thank you,

@jkenney9a
Copy link

This looks like the same problem we had here #3044. I haven't found any other solution than to close the IDE like you did.

@SamConti
Copy link
Author

SamConti commented Apr 8, 2019

Hi,

Yes I saw this topic, but solution is for C++ not python. So I get around the problem placing the code to read the camera in a separate *.py file and call it as a thread when needed (not tested as a simple function) = the code is executed, the file is automatically released and the problem doesn't occur.

@SamConti
Copy link
Author

SamConti commented Apr 9, 2019

Hello,

I up this topic because I have a problem I don't know to get around.
The camera need several seconds (at leaset 6-7s) for stabilization else depth image is not good, then during this time bag file is running and filling itself. He becomes too big in size and I would like just one good image inside. Is there a way to avoid this ?

@lramati
Copy link
Contributor

lramati commented Apr 11, 2019

Try

import pyrealsense2 as rs

pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 6)
config.enable_record_to_file("BagFile.bag")

auto dev = pipe.start(config).get_device().as<rs2::record>();

# Skip first 10 seconds to allow depth to stabilize
dev.pause()
sleep(10000) 
dev.resume()

# only record a frame every 5 seconds
while (auto fs = pipe.wait_for_frames())
{
     dev.pause();
     sleep(5000);
     dev.resume();
}

@SamConti
Copy link
Author

Hello,

There's a syntax error at this line auto dev = pipe.start(config).get_device().as<rs2::record>();

@RealSenseCustomerSupport
Copy link
Collaborator


Hi SamConti,

For getting a recorder device, you may do something like this:

profile = pipeline.start(config)
recorder = rs.recorder("BAG_FILE_PATH+NAME_TO_RECORD_TO.bag", profile.get_device())
...
recorder.pause()
...
recorder.resume()

Notes: with this, you can skip the line of setting up bag file name "config.enable_record(...)"
Hope this can help clarify.

Thanks!

@SamConti
Copy link
Author

Hi,

Just thank you.
I will perform more test but first test seems to be very good :)

Thanks!

@soarwing52
Copy link

soarwing52 commented May 15, 2019

Hi,
I'm doing the same thing, which is take one frame every few seconds.
but I found that I lost a lot of frames.

my structure is:

    pipeline = rs.pipeline()
    config = rs.config()
    config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 30)
    config.enable_stream(rs.stream.color, 1920, 1080, rs.format.rgb8, 30)
    config.enable_record_to_file(file_name)
    profile = pipeline.start(config)
    device = profile.get_device()
    recorder = device.as_recorder()
    rs.recorder.pause(recorder)

and I have the

    color_sensor = profile.get_device().query_sensors()[1]
    color_sensor.set_option(rs.option.auto_exposure_priority, False)

which to turn off auto exposure priority to record data

and my runtime screen is:

  try:
        while True:
            frames = pipeline.wait_for_frames()
            depth_frame = frames.get_depth_frame()
            color_frame = frames.get_color_frame()
            if not depth_frame or not color_frame:
                continue

and for recording I have:

               rs.recorder.resume(recorder)
                time.sleep(0.01)
                r_frames = pipeline.wait_for_frames()
                r_depth_frame = r_frames.get_depth_frame()
                r_color_frame = r_frames.get_color_frame()
                rs.recorder.pause(recorder)

I'm recording every second one frame on a moving car, road survey.
and my question would be

how can I confirm that I got one frame recorded?
I tried set the sleep longer but I'll get more frames if the exposure is set faster and none when its not ready

i also tried the

if not depth or not color:
continue

didn't work either

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants