Note that ArgusCamera is not a real camera device, it is an application that manages a camera.
So by default it tries to auto-tune gains, exposure, whitebalance.
The real camera in case of RPi v2 Cam is a bayer RG10 device.
So if you turn off auto-tuning and set exposure to real device, it may work:
import cv2
import subprocess
import time
def gstreamer_pipeline(
sensor_id=0,
capture_width=1280,
capture_height=720,
display_width=640,
display_height=480,
framerate=30,
flip_method=2,
):
return (
"nvarguscamerasrc sensor-id=%d gainrange=\"16 16\" ispdigitalgainrange=\"1 1\" aelock=1 awblock=1 ! "
"video/x-raw(memory:NVMM), width=(int)%d, height=(int)%d, 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 max-buffers=1 drop=True"
% (
sensor_id,
capture_width,
capture_height,
framerate,
flip_method,
display_width,
display_height,
)
)
min_exposure = 13
max_exposure = 29999
exposure_step = 500
exposure = min_exposure
# Open Pi Camera
cap = cv2.VideoCapture(gstreamer_pipeline(sensor_id=0), cv2.CAP_GSTREAMER)
while cap.isOpened():
# Grab frame
ret, frame = cap.read()
# Display if there is a frame
if ret:
cv2.imshow('Frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
start = time.time()
subprocess.check_output(['v4l2-ctl', '--set-ctrl', 'exposure='+str(exposure)]).decode("utf-8")
end = time.time()
print('time to set exposure %f seconds' %(end - start))
print(subprocess.check_output(['v4l2-ctl', '--get-ctrl', 'exposure']).decode("utf-8"))
print(subprocess.check_output(['v4l2-ctl', '--get-ctrl', 'gain']).decode("utf-8"))
exposure += exposure_step
if exposure > max_exposure :
exposure = min_exposure
# Close everything
cap.release()
cv2.destroyAllWindows()
However, you’ll see that it takes more than one frame (~ 40 ms on Xavier-NX without boosting clocks), so it may not be suitable for changing exposure on each frame.
It may be possible to do that using v4l2 interface from python. I remember this post:
You may also try to see what is under the hood with strace:
sudo apt install strace
strace v4l2-ctl --set-ctrl exposure=55
....
ioctl(3, VIDIOC_S_EXT_CTRLS, {ctrl_class=V4L2_CTRL_CLASS_CAMERA, count=1, controls=[{id=0x9a200a /* V4L2_CID_??? */, size=0, value=55, value64=55}] => controls=[{id=0x9a200a /* V4L2_CID_??? */, size=0, value=55, value64=55}]}) = 0
....
Someone better skilled may further help.