Not all parameters are supported by all cameras - actually, they are one of the most troublesome part of the OpenCV library. Each camera type - from android cameras to USB cameras to professional ones offer a different interface to modify its parameters. There are many branches in OpenCV code to support as many of them, but of course not all possibilities are covered.
What you can do is to investigate your camera driver, write a patch for OpenCV and send it to code.opencv.org. This way others will enjoy your work, the same way you enjoy others'.
There is also a possibility that your camera does not support your request - most USB cams are cheap and simple. Maybe that parameter is just not available for modifications.
If you are sure the camera supports a given param (you say the camera manufacturer provides some code) and do not want to mess with OpenCV, you can wrap that sample code in C++ with boost::python, to make it available in Python. Then, enjoy using it.
Answer from Sam on Stack OverflowNot all parameters are supported by all cameras - actually, they are one of the most troublesome part of the OpenCV library. Each camera type - from android cameras to USB cameras to professional ones offer a different interface to modify its parameters. There are many branches in OpenCV code to support as many of them, but of course not all possibilities are covered.
What you can do is to investigate your camera driver, write a patch for OpenCV and send it to code.opencv.org. This way others will enjoy your work, the same way you enjoy others'.
There is also a possibility that your camera does not support your request - most USB cams are cheap and simple. Maybe that parameter is just not available for modifications.
If you are sure the camera supports a given param (you say the camera manufacturer provides some code) and do not want to mess with OpenCV, you can wrap that sample code in C++ with boost::python, to make it available in Python. Then, enjoy using it.
I had the same problem with openCV on Raspberry Pi... don't know if this can solve your problem, but what worked for me was
import time
import cv2
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
time.sleep(2)
cap.set(cv2.CAP_PROP_EXPOSURE, -8.0)
the time you have to use can be different
i think finally i found a solution, at least for my problem,
capture = cv2.VideoCapture(id)
capture.set(cv2.CAP_PROP_AUTO_EXPOSURE, 3) # auto mode
capture.set(cv2.CAP_PROP_AUTO_EXPOSURE, 1) # manual mode
capture.set(cv2.CAP_PROP_EXPOSURE, desired_exposure_value)
i have to first set the auto_exposure to 3 (auto mode)
then i have to set it to 1 (manual mode)
and then i can set the manual exposure
you can set the settings with shell too
list available options
video_id=1
v4l2-ctl --device /dev/video$video_id -l
set them with python
def set_manual_exposure(dev_video_id, exposure_time):
commands = [
("v4l2-ctl --device /dev/video"+str(id)+" -c exposure_auto=3"),
("v4l2-ctl --device /dev/video"+str(id)+" -c exposure_auto=1"),
("v4l2-ctl --device /dev/video"+str(id)+" -c exposure_absolute="+str(exposure_time))
]
for c in commands:
os.system(c)
# usage
set_manual_exposure(1, 18)
It depends on the capture api you are using. If you are using CAP_V4L2, then automatic exposure is set to 'on' with value 3 and 'off' with value 1.
All settable values can be found by typing v4l2-ctl -l in terminal.
I think for OpenCV < 4.0 default api is CAP_GSTREAMER and automatic exposure is set to 'on' with value 0.75 and 'off' with value 0.25.
There is a method available to change properties of VideoCapture object in OpenCV which can be used to set exposure of input image.
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_EXPOSURE, 40)
However this parameter is not supported by all cameras. Each camera type offers a different interface to set its parameters. There are many branches in OpenCV code to support as many of them, but of course not all the possibilities are covered.
Same is the case with my camera. So I had to find a different solution. That is using v4l2_ctl utility from command line terminal.
v4l2-ctl -d /dev/video0 -c exposure_absolute=40
But this retains its value for current video session only. That means you have to start video preview first and then set this property As soon as VideoCapture is released, the exposure value is restored to default.
I wanted to control exposure within my python script, so I used subprocess module to run linux bash command. e.g.
import subprocess
subprocess.check_call("v4l2-ctl -d /dev/video0 -c exposure_absolute=40",shell=True)
For instance
I was trying with a c920 for a while whithout success, but sometimes worked, other not using this:
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_EXPOSURE, -4)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) # after not change the exposure
But finally I realized that I was setting the width and height just after, and so I change the order and now is working fine!! Don´t blow your mind trying to disable the CAP_PROP_AUTO_EXPOSURE flag!! Its not necessary(at least with c920 on windows)!!
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) # before works fine
cap.set(cv2.CAP_PROP_EXPOSURE, -4)
By the way, the range of exposure in C920 is from -2 to -11!!(on windows 10)
Thanks a lot