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

Hello everyone, greetings from Italy!

I’m using 2 raspberry pi cameras 2.1 and I’d like to set two different exposure times for them.

Anyone knows how to resolve this problem?

Running the following command in the terminal:

$ gst-inspect-1.0 nvarguscamerasrc

I can only see one parameter related to the exposure time, that is exposuretimerange = “low high”, there is no exposition-time parameter.
If I set low = high I should be able to set the exposition time, right?
Also, I’m using gstreamer pipeline, and I don’t really know how should I set this parameter, because I get the following error:
TypeError: not all arguments converted during string formatting

Can anyone help me?

Thank you very much!

Not tried with recent L4T releases, but you may have to lock autogain and autoWB.
You may try this old example.

1 Like

What do you mean with “to lock autogain and autoWB”?
Also, setting the exposure time of the camera means I should also change the framerate?

I’ll check the example for sure, thank you for the reply!

Two things:

  • if you have controlled lightening of the scene and want to adjust the exposure for a given luminosity, you would lock other auto-adjustments so that you can tune your exposure.
  • If you don’t, you may check form V4L the analog gain and exposure, as these may be controlled by Argus/ISP.

You may try to have exposure time shorter than frame period (1/fps).

1 Like

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