Saving raw frames from a running camera is the fastest way to make vision work repeatable. Once a handful of frames sit on disk, you can tune thresholds, retrain a detector or enroll a template against identical pixels, without a camera, a part or a production line in the loop. This guide shows how to capture frames from a machine vision camera, verify each frame's size with simple arithmetic, and write the buffer to PNG, BMP or RAW files you can replay offline.
If you have never built an offline workflow before, start with how to practice machine vision with offline images; this article covers the capture side of that loop.
What you need
- A camera whose acquisition you can trigger or free-run, for example an area scan camera such as the LS-CMR-0166, and the interface card that feeds it, like the LS-FGB-0004 PoE GigE card.
- Acquisition software that exposes frame buffers with width, height, pixel format and size in bytes.
- A library for writing image files. OpenCV writes PNG and BMP in one call; NumPy plus
imageioworks too. - Disk space: plan for width × height × bytes per pixel per frame, times your frame count.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
The byte-count check every capture should pass
Before any file is written, confirm the buffer matches the frame geometry. The expected size of an uncompressed frame is:
Bytes per pixel depends on the pixel format: 1 for mono 8-bit (Y8), 3 for RGB8 or BGR8, 2 for 16-bit or most 10/12-bit packed-into-16 formats. For a 1056 × 1920 Y8 frame the check is 1056 × 1920 × 1 = 2,027,520 bytes. If the acquisition reports 6,082,560 bytes for the same geometry, the frame is almost certainly three-channel: 1056 × 1920 × 3 = 6,082,560.
If the reported size does not match any plausible pixel format, stop and fix the acquisition before saving anything. A size mismatch usually means a partial frame, a corrupt header or an unexpected packed format, and every file you write from it is wasted disk. Truncated buffers also show up later as periodic gaps in image histograms, so this check saves a confusing debugging session downstream.
Step by step: capture and save frames
- Verify live acquisition. Open the camera, start streaming and confirm you receive consecutive frame numbers with a stable, expected byte count. Lock exposure and gain to fixed values so every saved frame is comparable; if exposure is drifting, the saved set inherits the drift. See camera exposure and gain units: interpreting raw values for what those settings actually mean.
- Freeze the lighting and part. For enrollment or template images, place the part in the pose you will see in production. Save frames across the full range of poses you must tolerate, not just the perfect one.
- Run the byte-count check from the previous section on the first frame. Do not proceed until the arithmetic matches.
- Convert the buffer to an array with the correct stride. If the driver reports a row stride larger than width × bytes per pixel, copy row by row using that stride. Skipping this step produces sheared or torn images.
-
Write the files. With OpenCV in Python,
cv2.imwrite("frame_%04d.png" % i, img)writes a lossless PNG. For RAW, write the packed bytes directly and record the geometry in a sidecar file. - Spot-check three files. Open the first, a middle and the last frame. Check dimensions, histogram and visual content. A capture loop that fails mid-run often writes a run of identical or empty frames at the end.
- Store metadata. Timestamp, exposure, gain, part ID and pass/fail label, one line per frame, in a CSV next to the images. Offline replay is only as useful as the labels attached to it.
- Interface
- GigE
PNG, BMP or RAW: which format to save
- PNG — lossless, compressed, opens everywhere. The default for inspection images, datasets and anything you will share. Compression is slower to write than BMP.
- BMP — lossless, uncompressed, trivial to parse. Fastest to write, largest files. Good when the write rate matters more than disk space.
- RAW — the exact sensor buffer, needed when you want to replay 10- or 12-bit data bit for bit. Nothing else can round-trip packed formats perfectly.
For a worked example, take a 12 MP camera with a 4000 × 3000 sensor. One mono 8-bit frame is 4000 × 3000 × 1 = 12,000,000 bytes, so 50 frames cost about 600 MB uncompressed. The same frames as RGB8 are 36 MB each and 1.8 GB for the set. PNG typically halves or thirds that at the cost of write time. Decide the budget before the capture run, not after the disk fills.
Using saved frames for enrollment
Enrollment workflows — storing a reference image or template a matcher will compare live parts against — need one extra discipline: capture the enrollment images on the same camera, lens and lighting the production system will use. A template enrolled on a different sensor or with different illumination will mismatch even on good parts. Save several enrollment images per variant and confirm the matcher accepts all of them before you trust the set. If your pipeline normalizes images first, live binary image preview for defect inspection shows how to check the intermediate result on saved frames before anything runs on line.
Common mistakes
- Stride ignored. Rows padded to a multiple of 4 or 64 bytes save as diagonal-streaked images. Always read the stride from the frame metadata.
- Byte order assumed. RGB versus BGR flips red and blue channels. Check one saved frame with a known color patch before capturing thousands.
- Auto exposure left on. Frames captured minutes apart are no longer comparable. Fix exposure and gain, and note them in the metadata.
- Overwriting the only good set. Version your capture directories. A re-capture under slightly different lighting silently invalidates every threshold tuned on the old set.
- Trusting the file size. A file can exist and still be a zero-padded buffer. The histogram spot-check in step 6 catches this.
Verify the capture worked
Before calling the set done, confirm three things. First, file count equals frame count: if the loop wrote 43 of 50 frames, the last write failed. Second, every file's size matches the byte-count formula for its format (PNG and BMP sizes are stable for identical geometry; RAW should match exactly). Third, decode the first and last RAW file with your recorded geometry and confirm the dimensions match. A saved set that passes these three checks will replay correctly offline, including through calibration — keep the calibration file with the frames, as covered in save camera calibration parameters for reliable reuse.
When saved frames are the wrong tool
Offline replay cannot catch problems that live between the camera and your algorithm: flaky cabling, intermittent trigger dropouts, or bandwidth limits that only appear at full frame rate. If a defect escapes a system that scores perfectly on saved images, test the live path — camera preview freezes after first frame: channel checks and camera hardware trigger frame rate with external pulses cover the usual live-side suspects. For uploading frames from a streaming pipeline to object storage, saving ROI frames from a DeepStream pipeline goes deeper on that specific path.
Quick checklist
- Byte count matches width × height × bytes per pixel.
- Stride from the frame metadata used, not assumed.
- Exposure and gain fixed and recorded.
- Pixel format and geometry in the file name or sidecar.
- First, middle and last frames spot-checked.
- Metadata CSV written with one labeled line per frame.
- Frames captured to local disk, copied afterwards.
When you are ready to capture, the camera finder lists area scan models, the accessories finder covers interface cards, and the system configurator walks camera, interface and software in one pass. Questions about matching a camera to your capture rate? Use the contact page and we will work through the numbers with you.
Questions
How do I check a captured frame is complete before saving it?
Multiply width by height by bytes per pixel and compare with the buffer size the acquisition reports. A 1056 x 1920 Y8 frame is 1056 × 1920 × 1 = 2,027,520 bytes; an RGB8 frame of the same size is 6,082,560 bytes. If the reported byte count matches the arithmetic but the saved file is smaller, your write step is truncating the buffer, not the camera.
Should I save PNG, BMP or RAW files?
Use PNG for inspection images you will open in tools or share, because it is lossless and compresses well. Use BMP when you want zero compression overhead and a trivial header to parse. Keep RAW when you need the exact sensor buffer, such as repeating a 10- or 12-bit capture bit for bit; record width, height and pixel format in the file name or a sidecar file so you can decode it later.
Why save frames at all instead of testing with the live camera?
Saved frames make algorithm runs repeatable: the same pixels every time, so a change in detection output is your code, not lighting drift or part placement. They also let you develop without the hardware attached and build enrollment or training datasets at production speed. Capture a mix of good and known-bad parts so the set covers the failures you actually need to catch.
How many frames should I capture for a test set?
For repeatability during development, 20 to 50 frames of each representative case is usually enough to debug an algorithm. For enrollment or template matching, capture at least 10 to 20 images per part variant across the full range of pose and lighting you expect on the line. For anything statistical, such as threshold tuning, aim for hundreds of frames spanning days of production, not one good shift.
The saved PNG opens but looks torn or shifted. What went wrong?
Almost always a stride mismatch: the driver may pad each row to a multiple of 4 or 64 bytes, so the buffer's row pitch is larger than width × bytes per pixel. If you write rows assuming a tight stride, each row starts mid-pixel and the image shears. Query the actual stride from the frame metadata and step through the buffer row by row, or copy into a tightly packed array first.

