Jetson Nano B01 - setting exposure times for two raspberry pi cameras

It’s definitely the first point then, because we will use a reflective panel to acquire an image inside a little box.

Last question:
how do I set the gstreamer pipeline for all these parameters? Do you have any example?
I’m using the “dual_camera.py” code given by JetsonHacksNano, but I don’t know how to add parameters to
the pipeline.
I think that sensor_mode must be deleted in order to choose the desidered framerate.
Moreover, if I add the parameter exposuretimerange, I also need to add it in the return sentence, but I find it quite intriguing:

return (
"nvarguscamerasrc sensor-id=%d sensor-mode=%d ! "
"video/x-raw(memory:NVMM), "
"width=(int)%d, height=(int)%d, "
"format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
“video/x-raw, format=(string)BGR ! appsink”
% (
sensor_id,
sensor_mode,
capture_width,
capture_height,
framerate,
flip_method,
display_width,
display_height,
)

What do I need to add to select the parameters you gave me?
I think I can see them with the command

$ gst-inspect-1.0 nvarguscamerasrc

but I don’t really know how to set them in the pipeline.

hello tooricco,

you may also refer to Argus samples, for example, Argus/public/samples/userAutoExposure/
thanks

1 Like

hello tooricco,

you may also add the exposuretimerange control property to your gst pipeline,
you should specify the exposure time range in nanoseconds,
for example,

  exposuretimerange   : Property to adjust exposure time range in nanoseconds
                        Use string with values of Exposure Time Range (low, high)
                        in that order, to set the property.
                        eg: exposuretimerange="34000 358733000"
1 Like

This is exactly what I was trying to do, setting the lowest value equal to the highest one:
eg: exposuretimerange=“50000 50000”.

I just can’t add the parameter correctly to the pipeline.
For instance, I could write something like:

return (
"nvarguscamerasrc sensor-id=%d sensor-mode=%d ! "
"video/x-raw(memory:NVMM), "
"width=(int)%d, height=(int)%d, "
"format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
“video/x-raw, format=(string)BGR ! appsink”
% (
sensor_id,
sensor_mode,
capture_width,
capture_height,
framerate,
flip_method,
display_width,
display_height,
exposuretimerange,
)

but I think I should also add something in the first part immediately after the return function, but I don’t know what should I write!

I checked the samples, but they’re writtein in C++ (that I don’t know unfortunately).
I’m using Python for my work.

Thanks for the reply!

You would set the pipeline such as:

"nvarguscamerasrc sensor_id=0 wbmode=0 awblock=true gainrange=\"8 8\" ispdigitalgainrange=\"4 4\" exposuretimerange=\"5000000 5000000\" aelock=true ! video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080,format=(string)NV12, framerate=(fraction)30/1 ! nvvidconv ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink"
1 Like

Thank you very much, I had some problems with the string formatting.

If I use sensor-mode=3 (which is 60fps, 1280x720) I can avoid to set the framerate parameter if I use exposuretimerange values less than 16ms, am I right?

I would advise to set the framerate so that another framerate wouldn’t be used.
The maximum exposure time for a given framerate depends on your sensor, you would check further or keep a small margin wrt to period.

1 Like

So, this is what I did so far.
As I said before, I’m using the code given by JetsonHacksNano.

I set the pipeline in the following way:

def gstreamer_pipeline(
sensor_id=0,
capture_width=1280,
capture_height=720,
display_width=1280,
display_height=720,
framerate=30,
flip_method=0,
exposuretime_low = 5000000,
exposuretime_high = 5000000,
):
return (
"nvarguscamerasrc sensor-id=%d, "
"video/x-raw(memory:NVMM), "
"width=(int)%d, height=(int)%d, "
"wbmode=0, awblock=true, gainrange="8 8", ispdigitalgainrange="4 4", "
"exposuretimerange="(int)%d (int)%d", aeLock=true, "
"format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
“video/x-raw, format=(string)BGR ! appsink”

    % (
        sensor_id,
        capture_width,
        capture_height,
        exposuretime_low,
        exposuretime_high,
        framerate,
        flip_method,
        display_width,
        display_height,
    )
)

Then I start the two cameras. For example, this is how I initialize the first one:

def start_cameras():
left_camera = CSI_Camera()
left_camera.open(
gstreamer_pipeline(
sensor_id=0,
exposuretime_low=1000000,
exposuretime_high=1000000,
framerate=30,
flip_method=0,
display_height=540,
display_width=960,
)
)
left_camera.start()

These are the only changes I did to the original code.
Unfortunately, I get this error when I run the code:

(python:7330): GStreamer-CRITICAL **: 13:06:07.953: gst_element_make_from_uri: assertion ‘gst_uri_is_valid (uri)’ failed
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (711) open OpenCV | GStreamer warning: Error opening bin: could not set property “sensor-id” in element “nvarguscamerasrc0” to “0,”
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (480) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created

(python:7330): GStreamer-CRITICAL **: 13:06:07.965: gst_element_make_from_uri: assertion ‘gst_uri_is_valid (uri)’ failed
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (711) open OpenCV | GStreamer warning: Error opening bin: could not set property “sensor-id” in element “nvarguscamerasrc1” to “1,”
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (480) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
Unable to open any cameras
Traceback (most recent call last):
File “dual_exp.py”, line 202, in
start_cameras()
File “dual_exp.py”, line 184, in start_cameras
_ , right_image=right_camera.read()
File “dual_exp.py”, line 88, in read
frame = self.frame.copy()
AttributeError: ‘NoneType’ object has no attribute ‘copy’

Can’t really figure out where the problem is, being the code exactly the same as before.
Maybe there is an error in the new pipeline?

You may try to remove the ‘(int)’ here.
Also, I don’t see the ‘\’ before ‘"’ in the pipeline string.

Additional note: not faced that, but in some cases aeantibanding may also have to be set off.

1 Like

I’ll try later and I’ll let you know about the int and the aeantubanding parameter (I don’t think this one was listed in the parameter list.

Regarding the ‘\’ before ‘"’ in the pipeline, there is no such thing even in the original pipeline, which is the following:

"nvarguscamerasrc sensor-id=%d sensor-mode=%d ! "
"video/x-raw(memory:NVMM), "
"width=(int)%d, height=(int)%d, "
"format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
“video/x-raw, format=(string)BGR ! appsink”

In the original pipeline, these were only quotes enclosing strings that will be concatenated.

But for the exposuretimerange argument, the string itself should contain quotes. In order to avoid these to be taken as end of string but rather to be chars in the string, you have to use a backslash before:

"nvarguscamerasrc sensor-id=%d, "
"video/x-raw(memory:NVMM), "
"width=(int)%d, height=(int)%d, "
"wbmode=0, awblock=true, gainrange=\"8 8\", ispdigitalgainrange=\"4 4\", "
"exposuretimerange=\"%d %d\", aeLock=true, "
"format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
"video/x-raw, format=(string)BGR ! appsink"
1 Like

Infact I put them in the code, I don’t know they weren’t displayed in the previous comment. I’ll try the changes you suggested,

So, I copied your pipeline but still got the same error as before.
My previous pipeline was:

"exposuretimerange= \"(int)%d (int)%d \", aeLock=true, "

so I don’t think this is the problem.
Maybe the pipeline is not being created correctly because of the parameter’s order? But this should not be a problem either.
I know that sounds dumb, could it be the position of , and ! in the pipeline that’s causing the problem?

You would just print the pipeline string as returned from you function and post it here in code block:

pipeline_str = gstreamer_pipeline()
print(pipeline_str)
1 Like

Sorry I didn’t understand what you mean

Your python code defines a function gstreamer_pipeline() that return the pipeline string. Printing it would allow you to copy it from terminal and post it here so that someone would be able to check.

I think I got it…You added these options to the output caps of nvarguscamerasrc, while these are nvarguscamerasrc options. Try:

def gstreamer_pipeline(
sensor_id=0,
capture_width=1280,
capture_height=720,
display_width=1280,
display_height=720,
framerate=30,
flip_method=0,
exposuretime_low = 5000000,
exposuretime_high = 5000000,
):
return (
"nvarguscamerasrc sensor-id=%d, wbmode=0, awblock=true, gainrange=\"8 8\", ispdigitalgainrange=\"4 4\", exposuretimerange=\"%d %d\", aeLock=true ! "
"video/x-raw(memory:NVMM), width=(int)%d, height=(int)%d, format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
"video/x-raw, format=(string)BGR ! appsink"
% (
        sensor_id,
        exposuretime_low,
        exposuretime_high,
        capture_width,
        capture_height,
        framerate,
        flip_method,
        display_width,
        display_height,
    )
)

Okay I understood, infact I was posting the pipeline output, which is:

nvarguscamerasrc sensor-id=0 video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, wbmode=0, awblock=true, gainrange="8 8", ispdigitalgainrange="4 4", exposuretimerange="5000000 5000000", aeLock=true, format=(string)NV12, framerate=(fraction)30/1 ! nvvidconv flip-method=0 ! video/x-raw, width=(int)1280, height=(int)720, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink

This time I got this error:

(python:7955): GStreamer-CRITICAL **: 16:32:41.347: gst_element_make_from_uri: assertion 'gst_uri_is_valid (uri)' failed
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (711) open OpenCV | **GStreamer warning: Error opening bin: no element "video"**
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (480) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created

(python:7955): GStreamer-CRITICAL **: 16:32:41.359: gst_element_make_from_uri: assertion 'gst_uri_is_valid (uri)' failed
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (711) open OpenCV | **GStreamer warning: Error opening bin: no element "video"**
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (480) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
Unable to open any cameras

I also understood your point, the order of the parameter is really important then. I used your part of code, but I’m still getting different errors, I could punch my monitor sooner or later :DDD
This time I’m getting these errors:

  1. Something similar to:
GStreamer warning: Error opening bin: could not set property "sensor-id" in element "nvarguscamerasrc0" to "0"
  1. This one is pretty awkward
Traceback (most recent call last):
  File "dual_exp.py", line 197, in <module>
    start_cameras()
  File "dual_exp.py", line 145, in start_cameras
    display_width=960,
  File "dual_exp.py", line 130, in gstreamer_pipeline
    display_height,
TypeError: not enough arguments for format string

This is the part of code I use to initialize the first camera (same code for the second one):

 left_camera = CSI_Camera()
    left_camera.open(
        gstreamer_pipeline(
            sensor_id=0,
            exposuretime_low=1000000,
            exposuretime_high=1000000,
            framerate=30,
            flip_method=0,
            display_height=540,
            display_width=960,
        )
    )
    left_camera.start()

I see some errors I did when modifying your code (I have not tested).
Plugin options are only separated by spaces, while caps properties are comma-separated.
You would modify the nvarguscamera options and remove the commas:

def gstreamer_pipeline(
sensor_id=0,
exposuretime_low = 5000000,
exposuretime_high = 5000000,
capture_width=1280,
capture_height=720,
display_width=1280,
display_height=720,
framerate=30,
flip_method=0,
):
return (
"nvarguscamerasrc sensor-id=%d wbmode=0 awblock=true gainrange=\"8 8\" ispdigitalgainrange=\"4 4\" exposuretimerange=\"%d %d\" aeLock=true ! "
"video/x-raw(memory:NVMM), width=(int)%d, height=(int)%d, format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
"video/x-raw, format=(string)BGR ! appsink"
% (
        sensor_id,
        exposuretime_low,
        exposuretime_high,
        capture_width,
        capture_height,
        framerate,
        flip_method,
        display_width,
        display_height,
    )
)
1 Like

hello tooricco,

please note that, the exposure time range settings were based-on nanoseconds,
your setting, exposuretimerange="5000000 5000000" seems a quite small exposure values.
please also check your sensor capability for the supported exposure-time values.
you may look into device tree for the min_exp_time and max_exp_time properties.
while you enable camera steam, there’ll also report the available ranges for each sensor modes.
for example,

GST_ARGUS: Available Sensor modes :
GST_ARGUS: 1280 x 1080 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 8.000000; Exposure Range min 17000, max 28220000;
1 Like