The image box stays white and the pixel array behind it reads nothing at all. The symptom is narrower than it looks: the display never received pixel data, so the frame stopped at one specific handoff between the sensor and the screen. This is for anyone integrating an area scan camera with a frame grabber or network card who has to prove where the data dies. Below is the working sequence: probe each handoff in order, confirm what should arrive at each one, and the first probe that shows nothing marks the failing stage. You also get the arithmetic for the most common cause — a transfer sized from a typed constant instead of from the frame.
What a white box with no pixels tells you
Three failures look alike and have different causes. A dark image means light or exposure reached the sensor badly. Dropped or out-of-order frames mean frames arrive but arrive late — a timing and bandwidth problem with its own diagnosis. A white box means the buffer behind the display was never written: no stage delivered pixels to the screen at all.
The distinction matters because an acquisition chain only moves data forward. Pixels cross seven handoffs: sensor to camera logic, camera to cable, cable to capture card or network port, card to driver buffers, driver to your grab call, grab to format conversion, conversion to the display control. The frame dies at exactly one of them, and everything downstream inherits the empty result.
So the question is never whether the camera is broken. It is how far the data gets — and a probe at each handoff answers that in minutes.
The probe points, in order
Put a check at every arrow in that chain and acquire one frame. In order:
- Device enumeration. The SDK's device list must show the camera. An empty list points at power, cable or driver — not at image data.
- The vendor grab example. Run the SDK's own grab program before any of your code. It is the fastest split in the whole diagnosis.
- The link. Link LEDs lit at both ends; for GigE, the port negotiating 1 Gbit/s.
- The card's frame counter. Capture cards and most drivers expose a frames-received counter. It must tick once per frame.
- The buffer after the grab. Probe the image object your grab call fills. Its size must be at least width × height × bytes per pixel, and some pixels must differ from the untouched value.
- The conversion output. If you convert pixel format — Bayer to color, 8-bit to 16-bit — probe the output's size and format, not just its contents.
- The display input. The control must read the same object the grab wrote.
Work top to bottom. The first check that shows nothing is your stage; everything past it is innocent.
Test 1: run the grab example before your code
This one test halves the search space. Start the grab utility that ships with the SDK, set it to continuous acquisition, and let it run.
If the example shows an image, the camera, cable, capture card and driver all work. Your bug lives in your program, so skip to the buffer, conversion and display checks below. Most white-box cases end here, at a line of code rather than a part.
If the example stays blank too, your code was never the suspect. Work down the chain instead: power and cable first, then the card.
One exception: a camera waiting for a hardware trigger acquires nothing until the trigger arrives, and even the vendor example shows an empty buffer. Set the camera to continuous mode for this test, then restore the trigger afterwards. If triggered acquisition is the suspect, hardware trigger stops after one frame: check acquisition mode covers the modes that silence a camera.
Test 2: power, link and cable
Power first, because a camera with no power sends no frames at all. If the camera takes power over its Ethernet cable, the capture port must deliver it: a plain network port leaves a PoE camera dark, and no software check will find that cause. The PoE card below powers cameras through the same cable that carries their frames.
- Interface
- GigE
- Ports
- 2 ports
Then the link and the cable, in the order that finds the fault fastest:
- Link state. Both link LEDs lit. On a GigE camera, confirm the port negotiated 1 Gbit/s: GigE Vision runs on Gigabit Ethernet, so a port that fell back to 100 Mbit/s cannot carry the stream.
- Reseat and lock. Pull and re-plug both cable ends. A half-seated RJ45 or M8 connector can pass power and link pulse while dropping frames.
- Cable fit. Match the cable to the interface and the motion: drag-chain runs need high-flex rated camera cables, static runs can go longer, and every connector keeps its lock fastened. The cards below cover the three common cases.
- Type
- Camera data cables
- Length
- 15 m
For the wiring-level version of this check, camera connected but no image: check the frame grabber cable wiring walks the lines in order.
Test 3: the frame grabber or network card
A frame grabber has one job — move each finished frame from the camera interface into host memory — so it answers the key question directly: did frames arrive? Open the card's status or diagnostic view and read the frames-received counter while acquiring.
- Counter ticks. Card and everything upstream work; the stop is in buffers or code. Go to the truncation test below.
- Counter stuck at 0 with a healthy link. The camera is not sending. Recheck camera mode, trigger and exposure before touching the card.
Then check the card's software side: the driver matching the card generation, and the driver's own buffers not exhausted. A driver that runs out of buffers drops frames; left long enough, that looks like none at all. The end-to-end acquisition path on Camera Link and CoaXPress hardware is laid out in frame grabber image acquisition for Camera Link and CoaXPress.
- Interface
- GigE
- Ports
- 4 ports
The truncation case: 256 rows in the frame, a loop that runs 4 times
The most common white-box bug is a transfer sized from a typed constant instead of from the frame. Here is the case with its own numbers.
Inputs. The display expects an 8-bit (U8) image of 256 rows — the frame height set in the program. The row-at-a-time transfer loop was given a fixed count of 4, typed by hand at some earlier edit. Both numbers come from the failing program itself.
Rule. A loop that copies one row per iteration must run once per row, so its count has to equal the frame's row count. The same logic sizes any buffer:
Arithmetic. Each iteration moves one row of C bytes, so the loop transfers 4 × C bytes into a destination sized for 256 × C bytes:
- rows filled = 4
- rows missing = 256 - 4 = 252
- fill_ratio = 4 / 256 = 0.0156, about 1.6% of the frame
- share left blank = 252 / 256 = 0.984, or 98.4%
Result. The display receives the top 4 rows; the other 252 are never written, and the control paints them as its untouched white value. Nothing is broken — the transfer is 252 rows short.
Decision. Any fill_ratio below 1.0, with valid pixels at the top of the frame, means a count or size mismatch. Take the loop count and the buffer size from the frame object's own height and width — 256 rows here — never from a typed constant. Fix that one value and the picture fills top to bottom on the next frame. The same arithmetic pre-checks multi-channel buffer sizes; when the shortfall sits in the driver rather than your loop, that is frame grabber buffer allocation errors.
Test 4: pixel format and conversion
Between grab and display there is often a format conversion: raw Bayer to color, 8-bit to 16-bit, planar to packed. A conversion only writes its output when the input format it was told about matches the buffer it actually receives.
Mismatched pairs produce plausible-looking empties. A mono source pushed through a color conversion, or an 8-bit buffer read as 16-bit, yields a correctly sized target full of nothing. A format the pipeline cannot handle shows up as a blank preview even while frames arrive.
Probe both sides of the conversion: the pixel format of the buffer the grab returned, and the format the display expects. If the grab returns raw Bayer and the preview stays blank, unsupported Bayer pixel format: diagnose a blank preview sorts out the format variants. After any fix, confirm the converted object reports its new format before anything reads it — converted image object pixel format: verify before processing shows that check.
Test 5: the display binding and buffer references
The last handoff is the one people skip: does the display control read the same image object the grab wrote?
Two failures dominate. First, two objects — the grab fills image A while the display shows image B, common in programs where the image was re-created after the display was wired up. Probe the display's input directly and compare object identity, not just size.
Second, references versus copies. Many SDKs hand back a reference into their own internal buffer rather than a copy, and that memory is reused as soon as you grab again or requeue. Read it too late and the display shows the reused, empty default. Copy out anything that must outlive the current grab iteration; stereo frames saved wrong: copy Mat data from the SDK buffer shows the failure pattern and the fix.
If the blank shows up not at the acquisition display but later, in a dataset or inference tool, run the same stage-by-stage pass on the preprocessing side; troubleshooting a grey blank image output in an inference pipeline covers that half.
Read the symptom, not the camera
Match what you see to a stage before touching anything:
| Symptom | Stage to suspect | Probe that confirms | Fix |
|---|---|---|---|
| White in your program, image in the vendor example | Code between grab and display | Probe the buffer right after the grab | Buffer size, conversion or binding (Tests 4 and 5) |
| White everywhere, link LED off | Power or cable | Reseat, check the port is PoE | Powered port, matched cable (Test 2) |
| White everywhere, link up, frame counter stuck at 0 | Camera waiting for a trigger | Switch to continuous mode | Trigger wiring or camera mode (Test 1) |
| Top rows valid, rest white | Transfer count mismatch | fill_ratio = rows moved / frame rows | Take the count from the frame height |
| One image, then blank forever | Buffer requeued before it was read | Probe right after the copy | Copy before requeue (Test 5) |
| Blanks come and go over minutes | Marginal link, packet loss | Driver packet statistics | Packet-loss diagnosis below |
Blanks that come and go have their own write-up in GigE Vision stream packet loss: diagnose blank frames. Frames that arrive but land late or out of order — the pipeline works but misbehaves — are the sibling case in camera image stream out of sync: recover the grab and check the link.
Stop it happening again
- Size buffers from the frame object at init. width × height × bytes per pixel, read from the camera. A typed constant survives every camera swap that follows it.
- Take loop counts from the frame height. The truncation case above was a 4 against 256; the fill_ratio check catches it in one run.
- Commission hardware with the vendor example first. It splits hardware faults from code faults before you read a line of your own program.
- Log a frames-arrived counter in your code. A counter that ticks proves the card; a counter that stops bounds the fault to your own stages.
- Match cables to motion and fasten every lock. High-flex on drag chains, screw locks on static runs.
- Assert the pixel format after every conversion. One check between conversion and display keeps format drift out of the picture.
Once the image flows, keep the chain matched end to end: the system configurator pairs camera, cable and capture card so the parts you order stream together, and the camera finder filters by interface, resolution and shutter if you are starting from the camera side. If a stage still returns nothing after these probes, bring your probe readings to the contact page and we will work the chain with you. The rest of the acquisition-side failures live on the systems topic page.
Questions
My image is black, not white — is this the same fault?
No. A white or untouched buffer means no pixel data was written at all, which points at the handoffs. A black image that only shows detail when you boost contrast is a lighting or exposure problem: check that the shutter opened and the trigger fired before touching the acquisition code.
How many buffers should a grab loop use?
For a simple grab-and-process loop, allocate three to five buffers. With one, the SDK reuses the memory while you process and frames overwrite each other; with three or more, one buffer can be displayed while the others fill. Size each one as width × height × bytes per pixel — a 4000 × 3000 mono8 frame needs 12,000,000 bytes, about 12 MB.
The vendor example shows an image but my program does not — what now?
The hardware is exonerated: camera, cable and capture card all work. The fault sits between the grab call and the display. Check that the grab writes into the same image object the display reads, that the buffer holds a full frame, and that any format conversion actually ran. That narrows the search from the whole machine to a handful of lines.
Does cable length alone cause a blank image?
Usually it causes lost or corrupted frames rather than a fully blank one, but a marginal link can fail so early that nothing arrives. Stay within the cable's rated length and bend spec, fasten every lock, and reseat both ends before deeper debugging. A camera on a drag chain needs a high-flex cable to keep the link stable.
Which probe type should I use between two stages?
Use the probe type that matches the wire: numeric probes on counters and buffer sizes, array or image probes on pixel data, and a status probe on error lines. Place one after the grab, one after allocation, one after conversion and one at the display input. The first probe showing nothing marks the failing stage, and everything past it is innocent.




