A point cloud export that needs 150 ms on a desktop can stretch to four or five seconds on an embedded board, and the camera is usually innocent. The delay comes from three places: formatting tens of thousands of vertices into text, copying per-vertex color you may not need, and pushing the result through a slow microSD card. This guide shows you how to find which of those dominates and how to cut the export time, in order of effort per second saved. It applies to any depth camera pipeline on a small ARM board, from ToF sensors to stereo heads.
Before changing anything, measure where the time goes. Time the export alone, then time writing a fixed-size dummy buffer to the same path. If the dummy write is fast, your cost is formatting; if it is slow, the storage is the bottleneck and no amount of code tuning will fix it. If you are also losing frames during capture, read high speed camera recording without dropped frames first, because a slow export that blocks the capture loop shows up as dropped frames, not as a slow file.
Why the export is slow
Three costs stack up in a typical SDK-style PLY export:
-
Text formatting. ASCII PLY converts every coordinate to decimal text with
sprintf-style calls. A 500,000-point cloud means 1.5 million number-to-string conversions, each of which is expensive on a low-power ARM core. - Per-vertex color. Texture adds three more fields per point, roughly tripling the data volume and adding color conversion on top. If your application only needs geometry, this is pure waste.
- Storage write throughput. A Class-10 microSD card sustains perhaps 20-40 MB/s in sequential writes and far less in small chunks, while a desktop NVMe SSD sustains thousands. A file that takes 150 ms on the PC takes seconds on the card for this reason alone.
The data volume is easy to estimate:
At 300,000 points, XYZ binary float32 is about 3.6 MB; the same cloud as ASCII with color is 15 MB or more. On a 25 MB/s card that difference alone is half a second.
Step 1: Export XYZ only, in binary
Strip the data you do not need. If the downstream step is a volume check, a height map or a clearance test, per-vertex color is dead weight.
- Build the vertex buffer with one interleaved
float32 x, y, ztriple per point. Skip invalid points where the depth is zero. - Write the PLY header as text:
format binary_little_endian 1.0, one elementvertexwithproperty float x,property float y,property float z, and the vertex count you actually wrote. -
fwritethe whole buffer in a single call, then close the file.
Keep a debug flag that switches the same writer to ASCII output, so you can open a file in a mesh viewer when something looks wrong. Binary files are also what you want when the cloud is later processed, for example when you store point cloud data in a voxel grid for 3D inspection, because the fixed record size lets you memory-map the file.
Step 2: Decouple capture from writing
Never write to storage inside the frame callback. Buffer frames in memory and flush them from a separate low-priority thread:
- Push each frame's XYZ buffer into a bounded queue as it arrives.
- Run a writer thread that drains the queue and appends to the file.
- When the queue is full, drop or merge frames deliberately rather than stalling capture.
This keeps capture latency stable even when the card has a slow moment. The same discipline prevents the surprise artifacts covered in periodic gaps in image histograms: diagnose export errors, where a blocked writer corrupts the stream in ways that look like a sensor fault. Size the queue against RAM: 100 frames of 3.6 MB is 360 MB, which is too much for many small boards, so either shrink the cloud or flush more often.
Step 3: Fix the storage, not the code
If the dummy-buffer test showed the medium is the limit, change the medium:
- Attach an SSD over USB 3 and write there; sequential throughput rises by an order of magnitude over a microSD card.
- Flush to a network share over gigabit Ethernet if a host PC is on the same switch, then post-process there.
- If you must keep the card, write large sequential blocks and avoid flushing per frame.
When the target is a network share, the cable quality and link negotiation genuinely matter; our cables range includes shielded Cat5e and Cat6 camera and data cables rated for locked, drag-chain installations. For capture-side links, camera GPIO wiring: prevent damage and triage power faults covers the connector side of the same harness.
Choosing the camera-side hardware
Export tuning only pays off if capture itself is stable. For geometry-only tasks, a depth camera without a heavy color pipeline keeps the host workload low.
- Type
- Depth / ToF camera
The MV-DT01WMU is a ToF sensing camera: a single depth stream, no stereo matching on the host, and a modest data rate that fits embedded boards. If you need structured-light accuracy on static parts instead, the MV-DPS200P-02 projects a pattern and returns a dense cloud from one shot.
- Type
- Stereo / structured light
Both sit in the 3D sensors category alongside laser profilers for conveyor work; browse the camera finder to filter by type. If the whole pipeline, sensor, host, storage and cabling, needs to be specced together, the system configurator walks the steps in order. For host hardware, an industrial mini PC with an M.2 SSD removes the storage bottleneck entirely.
Verify the result
After each change, time the same scene and check the file:
- Export the same cloud three times and take the median wall time.
- Open the file in a mesh viewer and confirm the point count matches the frame resolution minus invalid points.
- Spot-check one known distance against the live readout using center pixel depth measurement: read a fixed image point.
A correct implementation on a modest ARM board typically lands in the 500-800 ms range for a mid-sized XYZ binary cloud, which most inspection cycles tolerate once it no longer blocks capture.
When the usual answer is wrong
- Do not reach for compression first. Zipping the PLY shrinks the file but adds CPU work on the board; it helps only when the data must travel over a slow link, not when it lands on local storage.
- Do not write raw depth frames as a workaround unless you control the reader. Raw dumps are fast but lose scale and intrinsics; if you must go that route, link the geometry with camera intrinsic parameter conversion for depth and texture images so the file can be turned back into metric points later.
- Do not assume the SDK export is optimal. Convenience functions format text, copy color and flush defensively. A 50-line custom binary writer is one of the highest-return pieces of code in an embedded vision project.
Quick checklist
- Time a dummy write to the target path before touching code.
- Export XYZ-only binary float32 unless color is genuinely required.
- Save the color image as a compressed frame separately, if needed at all.
- Write from a separate thread with a bounded queue; never write in the frame callback.
- Move large sequential writes to SSD or a network share when the card is the limit.
- Verify point count and one known distance after every change.
Questions
Why is my PLY export ten times slower on an embedded board than on a PC?
The export loop is CPU- and storage-bound, and embedded boards have far less of both. Formatting each vertex into text, converting color, and writing thousands of small chunks to a microSD card each add cost that a desktop CPU and an NVMe SSD absorb without notice. The camera delivers the same data in both cases; the difference is entirely in formatting and write throughput. Measure the board's storage write speed first to see how much of the delay comes from the medium itself.
Does removing color from the PLY really help?
Yes, and it is usually the single largest win after binary format. Per-vertex color triples the amount of data per point and adds three integer-to-text conversions per vertex in ASCII mode. If your task only needs geometry, for example volume or clearance checks, export XYZ-only. If you still need the texture, save the color image separately as a compressed frame and keep the PLY geometry-only.
Is binary PLY always better than ASCII?
For machine-written and machine-read files, yes. Binary writes fixed-size records with no number formatting, typically an order of magnitude faster and smaller. ASCII is worth keeping only when a human must read the header or a downstream tool you cannot change requires text. Keep a debug flag so you can switch to ASCII for inspection while production runs use binary.
How much storage throughput do I need for real-time point cloud capture?
Multiply points per frame by bytes per point, then by frame rate. At 500,000 points, 12 bytes each and 15 fps you generate about 90 MB/s, beyond most microSD cards. Either reduce the point count, drop color, buffer and flush in bursts to an SSD over USB 3 or a gigabit network share, or accept that storage cannot keep pace with capture and decouple the two with an in-memory ring buffer.
Should I write the PLY myself instead of using the SDK export function?
Often, yes. SDK export functions are built for convenience and completeness, not speed, and they may format text, copy color and flush per chunk. A custom writer that emits a binary little-endian PLY with only the fields you need is short, portable and typically several times faster. Keep the format spec open when you write it so mesh viewers accept the file.
Will a faster cable fix a slow export?
Rarely. The camera-to-host cable affects capture, not file writing, and an export delay that appears after the frame arrives is downstream of it. The exception is a network share target: if you flush over gigabit Ethernet to a NAS, a damaged or incorrectly specified cable can cap throughput. Otherwise spend the effort on storage media and the writer itself.

