The camera for the line you are programming arrives next month, and the acquisition code is due now. A virtual USB camera solves this: a small driver presents stored images, a video file or your screen as a standard USB video stream, and your software lists it like any webcam. Most attempts fail the same way — the acquisition call rejects the device with an invalid-settings error, because the code requests a resolution and pixel format the virtual driver never offered. This guide shows you how to set one up on Linux and Windows, match its listed modes, and know exactly what the test proves — and what it cannot.
What a virtual USB camera is
A virtual USB camera is a driver, not a device. It registers a capture endpoint with the operating system and copies frames into it from a file, an image folder or a region of the screen. Your software enumerates it through the same UVC interface a hardware camera uses, so no vendor SDK is involved on either side.
On Linux the usual implementation is the v4l2loopback kernel module, which creates a /dev/video node that any V4L2 client can read. On Windows the equivalent is a driver that registers a DirectShow capture device. UVC is the USB class that lets cameras run without vendor drivers; we cover the real-hardware side of it in UVC-compliant USB cameras on embedded Linux.
Compared with a real camera, exactly three things differ: the mode list, the frame timing, and the exposure and gain controls — present in the enumeration, inert in practice.
Match the mode list before anything else
Open the virtual driver's own settings before you touch your code, and write down its listed modes. Screen-capture drivers typically expose one fixed combination: 640 × 480 pixels, 30 frames per second, packed RGB at 3 bytes per pixel. That list is the contract. Set your acquisition call to exactly one listed combination and the stream comes up; request anything off-list — 1920 × 1080, mono, 60 fps — and the negotiation fails with the invalid-settings error before a frame moves.
The fix lives in the request, not the driver. The same failure shape appears on real cameras: USB camera format negotiation: diagnose rejected modes walks that case, and why camera pixel formats are fixed shows why the sensor, not the software, decides the list.
If your saved test images are bigger than the driver's mode, scale them once: 4000 ÷ 640 = 6.25 and 3000 ÷ 480 = 6.25, so a 100-pixel inspection ROI becomes 16 pixels (100 ÷ 6.25) at driver scale. One uniform ratio keeps every coordinate translatable.
Set up the virtual camera on Linux
You need: the PC and OS your code targets, the acquisition software itself, a folder of representative test images, and the loopback video driver package for your distribution.
- Install the v4l2loopback package from your distribution's repository.
- Load the module so it creates one spare node; a new /dev/video entry appears beside any existing ones.
- Start a feeder that writes frames into that node — a video file, an image folder cycled at a fixed interval, or a captured screen region.
- Note the output mode the feeder and driver negotiated, for example 640 × 480 at 30 fps in RGB.
- List devices in your acquisition software; the new node appears beside any real cameras.
If the node never appears, work from the driver up: the module may not have loaded, or another process may hold the node open. The habit of checking the physical link first — USB camera not detected: check the cable before you swap hardware — applies here in software form: confirm the node exists before you blame the application.
Set up the virtual camera on Windows
- Install a virtual-camera driver that registers a capture device with DirectShow; several free drivers and apps do this.
- Pick its source: a folder of test images, a video file, or a screen region.
- Fix the output mode in the driver's settings and write the combination down.
- Open your acquisition software's device list and confirm the virtual device appears.
- Set width, height and pixel format to the written combination and grab one frame.
If the device shows in a chat client but not in your library — the classic symptom — the two applications are enumerating different device interfaces. Camera listed in one app but not another: DirectShow vs GenTL explains how to tell which interface your library actually reads.
Point your code at a listed mode
Every acquisition API exposes the same three inputs under its own names: frame width, frame height and pixel format. Set all three to the written-down combination; a partial match — right size, wrong format — fails the same way as no match at all.
// Illustrative names - use your SDK's equivalents
int width = 640; // pixels, from the driver's listed mode
int height = 480; // pixels, from the driver's listed mode
string pixelFormat = "RGB"; // its 3-bytes-per-pixel packed option
SetStreamParams(width, height, pixelFormat);
Frame frame = GrabOne();
// Test that proves the setup:
// frame.Width == 640, frame.Height == 480, frame.BytesPerPixel == 3
The check runs on the returned frame, not on the request: that is what separates a working configuration from an accepted one. Real sensors behave the same way — a fixed set of modes, negotiated rather than invented — which USB camera stuck at 4K: how sensor resolution modes work demonstrates on hardware.
Worked example: the rate the stream proves
Decide what the virtual stream proves by running the arithmetic for both cases:
USB 3 signals at 5 Gbit/s and carries roughly 4 Gbit/s of payload after line encoding, so a real bulk stream tops out near 400 MB/s. The production figure runs at about 90 percent of that ceiling; the virtual figure at about 7 percent. Your copy loops, buffers and allocator therefore run about 13 times lighter than they will in production (360 ÷ 27.6 ≈ 13).
So the virtual camera proves logic — decoding, conversion, storage, coordinate math. It does not prove bandwidth, sustained rate, or drop behaviour under load. Keep one hardware soak test in the plan.
What it can and cannot test
Proves: decoding and pixel-format conversion; ROI and coordinate math at the driver's scale; database writes, UI updates and the trigger-to-result state machine; algorithm behaviour on known inputs; nightly regression runs on a fixed image set.
Does not prove: exposure and motion blur; trigger jitter; sensor noise or shading; focus and depth of field; sustained bandwidth at production rates.
When you need richer coverage without the device attached, record and replay fixtures shows the record-once, replay-many pattern — real captured streams replayed as inputs, which covers the noise and timing a synthetic feed lacks.
Common mistakes
- Requesting the production camera's resolution and format instead of the driver's listed mode — the single most common rejection.
- Assuming mono input. Most feeders deliver RGB, and one forgotten conversion shifts your timing measurements by milliseconds per frame.
- Trusting the reported frame rate. A feeder on a fast PC can push 90 fps; that says nothing about a sensor locked to 30.
- Stress-testing bandwidth on the loopback device — the worked example above shows the gap.
- Blaming the application when the device never enumerates. Check the driver, the node and the feeder first.
Verify it worked
- The device list shows the virtual device with the exact mode you wrote down.
- A grabbed frame reports 640 × 480 at 3 bytes per pixel.
- Pixel values match the source: the first pixel of the grab equals the first pixel of the source image.
- Your processing loop holds a stable queue length across a 10-minute run.
- Request one off-list mode, such as 1920 × 1080 mono, and confirm you get the invalid-settings error — now you know its exact shape on your stack and will recognise it on real hardware.
If grabs intermittently come back black between setting changes, the capture mode is usually the cause: USB camera returns black images on most grabs: snap vs grab modes sorts the two.
When the pipeline passes, pick the real camera
Once decoding, ROI and storage run clean on the virtual stream, the remaining risk is the device itself: its mode list, its timing and the cable. The mode-matching habit transfers directly. Any of the area scan cameras in the shop — GigE, USB3, 10GigE or CoaXPress — enumerates a fixed mode list the same way.
For a USB3 test station, the LS-CMR-0166 delivers 4000 × 3000 at 30 fps over USB3 — the production rate from the worked example. Host it on a vision controller so camera ports and light channels share one box; the MV-VC2140-128G40-1T provides two USB 3 ports and four built-in light outputs. Both parts sit in the rail below.
- Sensor format
- 1/1.7"
- Interface
- USB3
- LAN ports
- 3-4 LAN ports
- USB 3 ports
- 2 USB 3 ports
To size the whole station — camera, lens, light, controller — start at the camera finder or the build configurator. More acquisition-side diagnostics live on the systems topic page, and the FAQ covers the commercial side. If you want the numbers checked against your parts before ordering, contact us — free expert support comes with every order.
Questions
Can a virtual USB camera measure field of view or pixel size?
No. Pixels in a virtual stream have no sensor behind them, so millimetres per pixel, distortion and depth of field are undefined. Use the virtual camera for logic and format handling, and compute optical numbers from the real sensor's format and pixel pitch. If you need a field of view, work it from the physical sensor and lens, then scale your test images to the same proportions.
Will the virtual camera show up in GenICam-based software?
Only if that library's producer enumerates UVC or DirectShow devices. Many vision libraries load their own GenTL transport layers, which list their own hardware and ignore a generic UVC device entirely. Check whether your library ships a UVC or DirectShow producer; if it does not, feed your test images to the algorithm directly in code rather than through a virtual device.
What frame rate does a virtual USB camera actually deliver?
Whatever the feeder produces or the application pulls. There is no sensor readout and no exposure time, so 30 fps on a virtual device is a counting rate, not a timing guarantee. Use it to check that your loop keeps pace with frames arriving at a fixed interval; measure real frame rate, trigger jitter and blur only on hardware.
How do I simulate a trigger with a virtual camera?
Feed images at your trigger interval. Most drivers accept a video file or an image sequence, so 90 images played at 30 fps behave like a 3-second production cycle and pace your processing loop realistically. This does not reproduce the exposure change a hardware trigger fires, nor the bandwidth dips a long cable introduces, so keep those checks for the bench.

