Cameras & sensorsExplainer

UVC camera exposure log2 units: why 0.125 s becomes 0.25 s

How UVC camera exposure log2 units work in Windows: the value is a base-2 exponent, 0.125 s must be sent as -3, and a natural-log slip sets 0.25 s.

LumaSpec Vision9 min read Share on LinkedIn

On this page 7 sections
  1. 01Exposure travels as a base-2 exponent, not a time
  2. 02Why a natural log sets twice the time you asked for
  3. 03Worked example: writing 0.125 s to a UVC camera in Windows
  4. 04The verification loop: write, read back, compare
  5. 05Where the convention appears, and where it does not
  6. 06When to leave the UVC layer behind
  7. 07Questions

You set 0.125 s on a USB camera under Windows and the image comes out about one stop too bright. The camera never saw 0.125: the UVC exposure control carries no seconds at all, only a base-2 exponent, and a software layer between you and the sensor converted with the wrong logarithm. Below are the convention, the arithmetic that turns the request into twice the time, a worked example you can check line by line, and a readback test that catches any driver making the same slip. It is for anyone wiring a UVC or DirectShow camera into a machine-vision application on Windows, and for anyone deciding whether a native-stack camera would remove the whole problem.

Exposure travels as a base-2 exponent, not a time

On Windows, a UVC camera's exposure control — the CameraControl_Exposure property of the DirectShow IAMCameraControl interface, usually reached over USB — is defined in log base 2 seconds, as the CameraControlProperty reference in Microsoft's DirectShow documentation states. For values below zero the exposure time is 1/(2^value) seconds; for zero and above it is 2^value seconds. Both branches reduce to one line: the control carries the base-2 logarithm of the exposure time in seconds. The newer Windows camera API keeps the convention; its VideoDeviceController exposure property is specified the same way.

Because the control takes whole numbers, the achievable times are powers of two:

Value sent Exposure applied
-4 0.0625 s
-3 0.125 s
-2 0.25 s
-1 0.5 s
0 1 s
1 2 s

Each step is a factor of two — one photographic stop. A 0.02 s request lands at 2^(-6) = 0.0156 s or 2^(-5) = 0.0313 s, so nearest-step rounding bounds the quantization error at a factor of 2^0.5 ≈ 1.41 either way, and only a power-of-two request is ever exact. That cap assumes the conversion itself is right. The next section shows what happens when it is not.

Why a natural log sets twice the time you asked for

To set a time, software must invert the convention, and that inversion needs a base-2 log. Substitute a natural log and the number sent is ln(t), which is ln(2) ≈ 0.693 times the correct exponent — always closer to zero. Rounding to the nearest whole number then lands short of the request, and short means a longer exposure.

For 0.125 s the correct value is log2(1/8) = -3. The natural log gives ln(1/8) = -2.079, which rounds to -2, so the camera applies 2^(-2) = 0.25 s: twice the request, one stop brighter. The gap widens as the time shrinks. A 1 ms exposure needs log2(0.001) ≈ -9.97, rounded to -10, but ln(0.001) ≈ -6.91 rounds to -7, and 2^(-7) = 7.8 ms — nearly eight times too long. Because the two logarithms differ by the constant factor 1/ln(2) ≈ 1.44, the error grows with every shorter decade, not by a fixed percentage.

This failure is not hypothetical. One machine-vision driver stack for DirectShow cameras shipped exactly this fault: a 0.125 s request sent from its configuration tool reached the camera as -2. The vendor traced the cause to the natural log and shipped a corrected driver release. The fault touched only the DirectShow path — typically USB cameras — because no other camera interface uses this control. The lesson generalizes: any generic driver layer between your code and a UVC camera earns the readback test below.

Worked example: writing 0.125 s to a UVC camera in Windows

Inputs. The requested exposure time is the eighth-second value from the field case: a DirectShow/USB camera driven through a vision driver's configuration panel. The conversion rule comes from the DirectShow exposure control definition linked above, and the control carries whole numbers only.

Rule in words. Send the base-2 logarithm of the requested seconds; the camera applies 2 to the power of minus that value.

value = log2(t_seconds) t_seconds = 2^(-value)

Arithmetic.

  • Correct path: value = log2(1/8) = -3. Check: 2^(-3) = 1/8 = 0.125 s.
  • Faulty path: ln(1/8) = -2.079, which rounds to -2. The camera applies 2^(-2) = 0.25 s.
  • Error factor: 0.25 s / 0.125 s = 2, one stop brighter than requested.

Result. The correct integer is -3. A stack that sends -2 has converted with the wrong logarithm base.

Decision. Read the value back immediately after writing. A readback of -3 means the path is clean, and any leftover brightness problem lives elsewhere — auto exposure still active, or exposure capped near the frame period (see why frame rate drops at longer exposure times). A readback of -2 means a layer between you and the camera converted wrongly: compute the integer in your own code, write it directly through the camera's control, or move to a driver release with the fix.

The verification loop: write, read back, compare

  1. Compute the integer yourself. value = round(log2(t)) using your language's base-2 log. Compute once, store it, and never let a driver guess on your behalf.
  2. Force manual exposure first. Many UVC cameras ignore exposure writes while auto exposure is active; if brightness keeps drifting after your write, that is auto mode working, not the log fault (see automatic iris, exposure and gain control).
  3. Write, then read back and require an exact match. A readback one step off is the signature of a conversion or clipping fault between you and the sensor; writing from your own code at runtime keeps the loop tight (see runtime camera exposure control).
  4. Confirm in the image. A fixed scene at twice the exposure sits exactly one stop brighter; if stepping the value by one doubles brightness, the exponent means what you think it means.
  5. Separate a refusal from a wrong conversion. A write that errors out or silently vanishes is a different fault from a converted value — a missing property or write protection (see camera exposure property not found).

On triggered machines there is one more mechanism to rule out: exposure may follow the trigger pulse width rather than the exposure control entirely (see why trigger pulse width sets exposure time).

Where the convention appears, and where it does not

The log base 2 rule lives in the Windows control layer, and OpenCV captures on Windows sit on that same layer for UVC devices — though UVC behaviour ultimately traces to the converter board behind the driver, as the OpenCV UVC autofocus case shows. The readback habit carries over unchanged.

Linux takes a different road. UVC exposure there runs through the V4L2 exposure_absolute control as a linear count in units of 0.1 ms, not as an exponent: a 0.125 s exposure is 1250 in these units, and a camera reporting a range of 1 to 5000 covers 0.1 ms to 0.5 s. Port nothing across directly — derive the Linux count from the seconds you want, the same way you derived the Windows exponent. If the camera fails earlier still — not enumerated at all on an industrial embedded Linux build — that is a kernel-side issue, covered in a guide to fixing a UVC camera that is not recognized on an embedded Linux kernel.

Native machine-vision interfaces skip the conversion altogether. GigE Vision, USB3 Vision and CoaXPress cameras carry exposure as a plain microsecond value in their GenICam feature map, read and written directly by your code. When you interpret the raw numbers those registers return, the exposure and gain unit guide covers what the values mean.

When to leave the UVC layer behind

The decision comes down to how exact the exposure must be:

  • Bench work, static scenes, generous light: stay on UVC. Pick power-of-two exposure times, run the readback test once at bring-up, and the layer does no harm.
  • Strobes, fast belts, blur budgets in tens of microseconds: leave the layer. Whole-number exponents cannot express a 100 µs flash better than 2^(-13) = 122 µs — 22% long — and a wrong-log stack misses by whole stops. Use a camera with a native stack, where exposure travels as an exact microsecond number. The area scan cameras range and the camera finder filter by interface, and the camera configurator walks the full chain from sensor to cable.
  • Camera inside your machine: the same logic applies at board level. The board-level cameras range carries USB3 modules built for embedding:
Board-level cameras3.1 MP USB3 board-level camera, IMX252, 1/1.8" global shutter, 120 fps (LS-BCM-0003)LS-BCM-0003
Sensor format
1/1.8"
Lens mount
C-mount
$690.00View part
Board-level camerasHikrobot MV-CB060-10UM-B 6 MP Board Level Camera, USB3, IMX178, Mono, Bare Board, V4MV-CB060-10UM-B
Sensor format
1/1.8"
Interface
USB3
$239.00View part

For choosing among them — mount, sensor, frame rate, driver — the board camera selection checklist walks the decisions in order.

If a build stalls on exposure behaviour you cannot pin down, send the scene, the cycle time and the camera interface through the contact page, or browse the rest of the cameras topic for the surrounding set-up guides.

Questions

What exposure value should I send for 1 ms on a UVC camera?

Compute the base-2 log of the seconds: log2(0.001) = ln(0.001)/ln(2) ≈ -6.908/0.693 ≈ -9.97, which rounds to -10. The camera then applies 2^(-10) ≈ 0.977 ms. The control takes whole numbers only, so a non-power-of-two time is not expressible — pick the power of two your tolerance accepts, write -10, and read the value back to confirm the driver chain kept it.

Do GigE Vision or USB3 Vision cameras use log2 exposure units?

No. The log base 2 seconds convention belongs to the Windows UVC and DirectShow exposure controls. Native machine-vision cameras run their own drivers and carry exposure as a plain microsecond value through the GenICam ExposureTime feature, so the base-2 conversion — and the natural-log fault it invites — never happens. If you see log2-style integers on such a camera, the conversion is happening in the software layer, not the camera.

I wrote the correct value but brightness did not change — what now?

Check the auto/manual mode flag first: many UVC cameras ignore manual exposure writes while auto exposure is active, and exposure or gain keep drifting on their own. If manual mode is on, read the value back; a readback that differs from your write means the layer between you and the camera converted or clipped it. If the readback matches but the frame rate dropped, the sensor may be capping exposure at the frame period.

How do Linux UVC exposure units differ from Windows?

Linux exposes UVC exposure through V4L2 as a linear count in units of 0.1 ms, not as an exponent. A 0.125 s exposure is 1250 in these units, and a camera reporting a control range of 1 to 5000 covers 0.1 ms to 0.5 s. A value that behaves correctly under Windows means nothing under Linux, so recompute before porting your set-up.

How far can a UVC exposure land from the time I asked for?

UVC controls take whole-number exponents, so the achievable times are powers of two. A 100 µs request becomes 2^(-13) = 122 µs, about 22% long, and nearest-step rounding caps a correct stack's error at a factor of 2^0.5 ≈ 1.41. A stack carrying the natural-log fault misses by whole stops rather than percentages, which is why the readback test matters on first bring-up.