A timed capture from a GigE camera fails in three predictable places: frames arrive 8-bit when the plan said 12, the rate sags below what the link should carry, and the clock in the file names drifts away from the clock in the instrument log. This is the loop for a scripted session — a deep-water camera logging beside a CTD, a bench recording a burst, any job where code sets the start, the count, the format and the stop. You will set the pixel format first, fix the rate or hand the camera a trigger, size the buffers so nothing drops, name every TIFF by its timestamp, and put both clocks on one NTP or PTP source so the two logs join after the fact.
What you need before the first frame
Two of the pieces decide the run before you write a line of code.
Camera. A GenICam camera exposes its features as named nodes, and the SDK that ships with the camera reads and writes them; PixelFormat, the frame-rate node and the trigger line are the three this job turns on. The area scan cameras page filters bodies by interface, resolution and shutter.
Host NIC. Enable jumbo frames on the NIC and on any switch in the path; the default 1,500-byte MTU chops every image into small packets and wastes the link. Where the camera sits beyond a power outlet, a PoE NIC carries data and power on the same cable.
- Interface
- GigE
- Ports
- 2 ports
Disk and clock. Size the disk for the stream rather than the link peak — the worked example below puts a number on that for a 5 MP case. Choose the time source now: one NTP or PTP server for the camera host and every instrument, not two clocks left to drift.
Set the bit depth first: PixelFormat sets bytes per frame
PixelFormat is the node that decides what every frame costs, and a timed session writes it before the stream starts — most cameras refuse a format change while acquiring.
The enumeration the camera reports lists the mono formats side by side. Mono8 sends one byte per pixel. A 12-bit format comes in two shapes: unpacked, each pixel travelling in a 16-bit container at two bytes, or packed, two pixels sharing three bytes at 1.5 bytes per pixel. The choice is the bandwidth budget, not a detail.
Pick the shallowest format that keeps the measurement honest. Mono8 halves the cost when eight bits of contrast carry the feature; take 12-bit when the analysis rescales per scene, calibrates intensity, or reads dark and bright regions of one frame. Expect the change to ripple through the run: on GigE a format switch moves the rate more than any other setting, and two failure modes get their own write-ups — the Bayer and BGR mix-up that halves the rate and linked attributes that shift when the format changes.
A 6 MP mono GigE camera is the classic host for this kind of scripted capture.
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Interface
- GigE
- Resolution
- 6-10 MP
Give the camera its rate: fixed frame rate or a trigger
Fixed rate. Switch on the camera's frame-rate control and write the target to its frame-rate node. At 20 fps the period is 1,000 ms ÷ 20 = 50 ms, and exposure and readout must both fit inside it: set exposure a few milliseconds short and the rate holds; let exposure plus readout overrun and the camera drops frames quietly. The accounting is the same on a trigger — maximum frame rate on a hardware trigger: exposure plus readout time — and longer exposures have their own GigE frame rate versus exposure time write-up.
Trigger. When events rather than the clock should gate frames — a door opens, a sampler fires — set the acquisition mode first, then the trigger line. The classic fault is one frame and then nothing, which has its own acquisition-mode fix, and the pulse wiring is covered in external pulses setting the frame rate.
The trigger rate becomes the frame rate, and the link still carries it: 20 fps of 10 MB frames saturates GigE in triggered mode exactly as in free run. If triggered frames arrive slow, this triggered frame rate troubleshooting guide walks the queue and exposure checks in order.
The timed loop: start, count, save, stop
Seven steps, each one a feature write or a call the SDK names after the node.
- Open the camera and write PixelFormat to the chosen mono format, before the stream starts.
- Enable frame-rate control and write the rate — or set the acquisition mode and trigger line for an event-driven run; the per-camera trigger configuration checklist keeps the free-run default from coming back.
- Write exposure a few milliseconds under the frame period, and gain with it.
- Allocate a ring of buffers once — 30 to 100 for a bursty run — and reuse them every frame. Per-frame allocation is the top cause of a rate that decays over a long session; buffer reuse instead of per-frame allocation shows the pattern.
- Start acquisition on your command and log the start time from the host clock.
- For each frame, take a buffer, read the frame's own timestamp, build the file name from the host clock as roi.yyyy.mm.dd.hh.mm.ss.msec.tif, write the TIFF, and return the buffer.
- Stop after the set count or on the stop command, log the stop time, and compare the file count with the count the camera reports.
Keep two times per frame. The wall-clock time in the file name is the join key against the instrument log; the camera's frame timestamp, written to a one-line-per-frame side file, survives a host clock that steps mid-run. A Python grab loop that acquires and saves each frame runs steps 4 to 6 end to end, and tuning an acquisition loop for sustained frame rate covers the host-side scheduling that keeps the rate flat for hours.
Worked example: 5 MP frames at 12-bit over GigE
Inputs, and where each comes from: width 2,448 px and height 2,048 px, a 5 MP frame — the classic resolution of this camera class. Bytes per pixel come from the formats themselves: 1 for Mono8, 1.5 for packed 12-bit, 2 for 12-bit in a 16-bit container. The link budget is about 115 MB/s sustained, what a tuned GigE path with jumbo frames typically holds: the line rate is 1 Gbit/s = 125 MB/s, protocol overhead takes the rest, and real links land between 105 and 118 MB/s.
The rule in words: frames per second times MB per frame must stay under the sustained rate, so the cap is that rate divided by the frame cost.
- Mono8: 2,448 × 2,048 = 5,013,504 px; × 1 B = 5,013,504 B ≈ 5.0 MB per frame. Cap: 115 ÷ 5.01 ≈ 22.9, so budget 22 fps.
- Packed 12-bit: 5,013,504 px × 1.5 B = 7,520,256 B ≈ 7.5 MB. Cap: 115 ÷ 7.52 ≈ 15.3, budget 15 fps.
- 12-bit in a 16-bit container: 5,013,504 px × 2 B = 10,027,008 B ≈ 10.0 MB. Cap: 115 ÷ 10.03 ≈ 11.5, budget 11 fps.
| Pixel format | Bytes per pixel | MB per frame (2,448 × 2,048) | GigE cap | 10GigE cap |
|---|---|---|---|---|
| Mono8 | 1 | 5.0 | ~22 fps | ~229 fps |
| Packed 12-bit | 1.5 | 7.5 | ~15 fps | ~152 fps |
| 12-bit, 16-bit container | 2 | 10.0 | ~11 fps | ~114 fps |
Decision, with the threshold stated: when frames per second × MB per frame passes about 115 MB/s, the format or the link has to change. Ask for 20 fps at 12-bit in a 16-bit container and the demand is 20 × 10.03 = 200.6 MB/s, 1.7× the GigE budget — that combination cannot run. The three exits: drop to Mono8 for the full 22 fps; keep 12-bit but packed at 15 fps; or leave GigE. A 10GigE path sustains roughly 1,150 MB/s, ten times the GigE figure, so the same 10.0 MB frame caps near 1,150 ÷ 10.03 ≈ 114 fps; a short USB3 run holds on the order of 400 MB/s, about 40 fps at that frame cost.
One number is still open: the camera's own rate at the chosen format. Sensor readout sets a ceiling of its own, and a run holds the lower of sensor ceiling and link cap, so take the camera's fps figure for your format before you promise a rate.
When the budget says leave GigE
For one camera a few metres from the host, USB3 moves on the order of 400 MB/s sustained with no switch in the path. When the job wants resolution as well as bit depth, a 20 MP USB3 mono body keeps the bytes moving without a frame grabber.
- Sensor format
- 1"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 16-25 MP
Longer cable runs and multi-camera hosts favour 10GigE: it is Ethernet, so ordinary switches and copper or fibre runs behave like any other network at ten times the budget. The host side needs a copper 10GbE NIC, and the frame grabbers category holds the cards from PoE NICs to 10GigE ports.
- Interface
- 10GigE
- Ports
- 4 ports
Put camera and instrument clocks on one source
Two clocks left alone drift apart by seconds a day — too much to join logs after a long deployment. Discipline every clock to one source and the join becomes a sort.
Network NTP on a switched LAN lands within a few milliseconds, enough when the instrument samples at 1 Hz: a 10 ms error is 1% of one interval. For events below about 50 ms, move to PTP (IEEE 1588): with hardware timestamping on camera, switch and host, agreement drops to the microsecond region. GigE Vision 2.0 includes IEEE 1588 in the standard, so look for a PTP feature in the camera's node list and put a PTP-aware switch in the path.
Record both times per frame regardless. The wall-clock time in the file name is the join key; the camera's frame timestamp never steps backwards when NTP corrects the host, which is what camera frame timestamp versus system time untangles at the join step. For the after-the-fact pairing: sort the TIFF names, take the instrument record nearest each file time, and interpolate the instrument values across its interval when the camera frames come far faster than the samples.
Checks before the long run
A deployment you cannot revisit earns a bench rehearsal. Run these in order:
- Grab ten frames and open one: the TIFF's bit depth tag matches the format you set, and the file size matches the bytes-per-frame arithmetic above.
- Run the full planned duration at full rate and count the files afterwards; the count is the first thing a dropped frame breaks.
- Watch the dropped-frame and overflow counters while the burst runs — 12-bit formats add 50-100% to per-frame size, and short buffer queues overflow first; troubleshooting GigE camera buffer overflow errors lists the queues to lengthen.
- Read the offset the NTP or PTP client reports and write it into the run log beside the start time.
- Re-run the file-name-versus-instrument join on the bench data before the system ships.
When the usual answer is wrong
A fixed frame rate is wrong when the scene gates the frames; trigger instead, and the pulse source becomes the metronome. Twelve bits are wrong when eight carry the decision — Mono8 hands back the whole GigE budget, and the worked case climbs from 11 to 22 fps. Host-clock-only naming is wrong when instruments sit on different machines or the run outlasts the drift budget: NTP covers milliseconds, PTP the region below. And GigE itself is wrong once frames per second × MB per frame passes roughly 115 MB/s; that multiplication is the whole decision, and every other number above feeds it.
Pick the parts, then start the bench run
Size the camera from the rate you actually need — format, frames per second, bytes per frame — then let the configurator match body, NIC and cable to it, or browse the camera finder by interface and shutter. The trigger, clock and buffer fixes from the rest of the timed-capture work sit on the systems topic page.
The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.
Questions
How much disk write speed does a 12-bit GigE stream need?
Match the drive to the stream, not to the link's peak: steady write throughput equals frames per second times MB per frame. The 5 MP worked case at 12-bit in a 16-bit container and 20 fps needs 20 × 10.0 MB ≈ 201 MB/s held for the whole run. Pick a drive and filesystem that benchmark above that with margin, and test at full length before deployment.
Does 12-bit in a 16-bit container change what my analysis sees?
The values sit in the low bits of the container: a 12-bit read through a 16-bit format tops out near 4,095, not 65,535. Keep the format constant across a campaign, and rescale by the sensor's bit depth rather than the container maximum, or 12-bit data will look 16 times darker than 8-bit data from the same scene in a naive script.
How close do camera and CTD clocks need to be?
Set the tolerance from the instrument's sample interval. A CTD logging at 1 Hz tolerates a 10 ms clock error — 1% of one sample — and network NTP on a switched LAN meets that with margin. For events shorter than about 50 ms, move to PTP with hardware timestamping on camera, switch and host, and keep logging the camera's own frame timestamp beside the file names.
Do I need a frame grabber for one GigE camera?
No. One GigE camera at a moderate rate runs on a standard NIC with jumbo frames enabled, typically a 9,000-byte MTU. Multi-port PoE and 10GigE cards earn their slot when several cameras share one host, when the cable must carry power, or when the stream passes about 115 MB/s. Match the card's port count to the camera count and keep one camera per port at high rates.
Which pixel format should a 12-bit sensor run when the features need only 8 bits?
Run Mono8. The format only decides what the camera transmits, so you give up the shadow and highlight latitude a radiometric measurement needs and get half the bytes per frame back. Keep 12-bit when the analysis rescales per scene, calibrates intensity, or reads features in dark and bright regions of the same frame.



