UVC camera exposure timing in OpenCV

6 Comments

USB cameras can have the exposure set to manual (cheaper ones have only full auto mode). It’s a pretty straight forward function in OpenCV, but insufficiently documented thus hard to find exact times and calculations. Also there are two major implementations for Linux and Windows.

  • Linux – exposure times are set in units 1/s (all clear here)
  • Windows – exposure times are selected from a table where index ranges typically from 0 to -13. Value 0 means the longest exposure and -13 is the shortest time (fastest shutter).

Windows indexed exposure values are a logarithmic function of time. The equation is very simple EXP_TIME = 2^(-EXP_VAL) and exact values listed in the table below.

CAP_PROP_EXPOSUREActual exposure time
01s
-1500ms
-2250ms
-3125ms
-462.5ms
-531.3ms
-615.6ms
-77.8ms
-83.9ms
-92ms
-10976.6µs
-11488.3µs
-12244.1µs
-13122.1µs

This results in a straight graph on the logarithmic scale.

And simple python code example is listed below. It Opens the camera, prepares fro MJPEG stream, and displays the real-time view on the screen.

import cv2

print("Initializing camera")

camera = cv2.VideoCapture(0)
print("Setting camera mode")

exp_val = -6

codec = 0x47504A4D # MJPG
camera.set(cv2.CAP_PROP_FPS, 30.0)
camera.set(cv2.CAP_PROP_FOURCC, codec)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
camera.set(cv2.CAP_PROP_EXPOSURE, exp_val)

print("Starting capture")
while(1):
	camera.grab()
	retval, im = camera.retrieve(0)
	cv2.imshow("image", im)

	k = cv2.waitKey(1) & 0xff
	if k == 27:
		print("exit")
		break

camera.release()
cv2.destroyAllWindows()

Comments ( 6 )

  1. fabio
    Thanks a lot! That is explaining why my code would not work on a Linux machine... Can I ask you whether you found this info on some documentation or you just worked it out yourself? I still did not get clearly what is the value that we are setting in the Linux case (in fact it looks on my machine as if I just have to remuve the negative sign). Thanks again!
    • saulius
      Hi Fabio, actually for Linux you can set exposure time directly and have much more values than range from -0 to -13. Will write about this some other day. Regarding camera initialization sequence - OpenCV changes camera code (well, actually not opencv itself, but camera separate libraries) from time to time and initialization sequence also changes. See more details here https://www.kurokesu.com/main/2020/07/12/pulling-full-resolution-from-a-webcam-with-opencv-windows/ and here https://wiki.kurokesu.com/shelves/cameras Due to lack of documentation and correct answers on the forums, had to work this out by myself.
  2. hari
    Thanks for the blog. Is it possible to get linear exposure time control in Windows , if yes, How? Like specified in UVC class specification 1.5 , Exposure time(absolute) control value 1 is for 100 μs , 10 is for 1 ms
    • saulius
      Hi Hari, standard OpenCV Windows implementation does not have this functionality
  3. bakijo
    Thanks a lot !! Could not figure out why my video feed was set to such high exposure even though I put the arg to 0.
    • saulius
      0 is the longest exposure.

Leave a Reply to fabio Cancel reply

Your email address will not be published.