UVC camera exposure timing in OpenCV

2 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 ( 2 )

  1. Replyfabio
    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!
    • Replysaulius
      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.

Leave a reply

Your email address will not be published.