Perimeter & border deployments
Turning a fence line, a checkpoint or a restricted area into events, using the same four calls everything else uses. Includes the things that go wrong at 3am, which is when security deployments are actually judged.
Why this SDK suits the work#
Three properties matter more here than anywhere else, and they are the ones this SDK was built around:
| Property | Why it decides the deal |
|---|---|
| Inference on the device | The site cannot send footage to a vendor. Often it is not allowed to, and often there is no link to do it with. |
| A real air-gapped path | Licensing that requires a phone-home is licensing that cannot be deployed at a border post or inside an OT boundary. See Air-gapped deployment. |
| Counts, not imagery | What leaves is inferences, frames, stream-seconds and events. That list is the entire answer in a security review. |
Note
The SDK contains no facial recognition, no biometric matching and no cross-camera re-identification. It detects people, vehicles and objects, tracks them while they are in frame, and reads number plates. That is a deliberate product boundary. For most buyers it shortens the privacy assessment considerably, and it is worth stating explicitly in your own documentation.
The primitives, mapped#
Most of physical security falls out of four calls:
| Requirement | Implementation |
|---|---|
| Virtual fence / border line | xcaicx_stream_add_line() — directed, so ingress and egress are different events |
| Restricted or sterile area | xcaicx_stream_add_zone() polygon |
| Loitering | dwell_seconds on a zone; fires once per visit |
| Intruder vs vehicle triage | Detection classes, with stable track ids |
| Checkpoint throughput | Lane zones for occupancy plus ANPR |
1. Perimeter intrusion#
A directed tripwire just inside the fence line, not on it.
/* Inside the fence, running parallel to it. */
int32_t line_id = -1;
xcaicx_stream_add_line(stream, "north-fence",
(xcaicx_point){0.08f, 0.62f},
(xcaicx_point){0.94f, 0.48f}, &line_id);if (e->kind == XCAICX_EVENT_LINE_CROSS && strcmp(e->zone_name, "north-fence") == 0) {
if (strcmp(e->detail, "a_to_b") == 0) alarm_ingress(e->track_id, e->pts_us);
else log_egress(e->track_id, e->pts_us);
}Direction is the difference between an alarm and a log line. A patrol walking out should not raise what a breach raises.
Careful
Place the line inside the frame, not at its edge. A track is only confirmed after min_hits (default 3) detections. Something entering at the very edge of the frame can cross a boundary drawn there before it is confirmed, and the crossing is silently missed. Give the tracker a few frames of run-up.
Tuning for a fence line#
| Symptom | Change |
|---|---|
| Vegetation and shadows raising alarms | Raise detect_threshold; the reference backend keys on contrast and will find a moving shadow |
| Animals triggering the line | Classes are aspect-ratio based; filter on class_name == "person" and accept that a crouching person is a harder case |
| Fast vehicles crossing unseen | Lower detect_every_n, or raise the frame rate. Do not lower min_hits — that re-admits the false positives you just removed |
| One intruder raising many alarms | You are counting detections, not tracks. Alarm on track_id transitions |
2. Restricted areas and loitering#
const xcaicx_point sterile[] = {
{0.30f, 0.40f}, {0.92f, 0.34f}, {0.96f, 0.95f}, {0.26f, 0.98f}
};
int32_t zone_id = -1;
xcaicx_stream_add_zone(stream, "sterile-area", sterile, 4,
/*dwell_seconds=*/30, &zone_id);Zone membership is tested at the midpoint of the bottom edge of a track — the ground contact point. Draw zones on the floor plane as they exist in the world; a zone drawn around where a person's torso appears in the image will never trigger.
DWELL_EXCEEDED fires once per visit. Someone crossing the area produces enter and exit; someone stopping in it produces enter, dwell, and later exit. That distinction is usually the whole alarm policy.
3. Border segment monitoring#
The same tripwire, with two differences in practice:
- Group crossings. Each person is a track with an id, so a group is a countable set of
LINE_CROSSevents rather than one. Deduplicate ontrack_id, not on time. - Long, shallow fields of view. Objects are small at range. Analysis runs at 320px on the long side, so a person who occupies fewer than roughly ten pixels of height at that scale will not be detected. That is a lens, mounting and camera-count question, not a tuning one — work it out before installation rather than after.
Do not
Do not solve small-object detection by feeding 4K. Frames are downscaled to 320px for analysis regardless, so the extra resolution costs conversion time and buys nothing. Solve it with focal length, camera placement, or more cameras.
4. Vehicle checkpoints#
cfg.modules = XCAICX_MODULE_DETECT | XCAICX_MODULE_ANPR;Plate localisation runs on any build. Reading the characters requires a production build with the text model — the reference backend returns the plate box with empty text and detail = "plate_candidate". Check for that in bring-up so you do not mistake a working pipeline for a working reader.
for (size_t i = 0; i < res->detection_count; ++i) {
const xcaicx_detection *d = &res->detections[i];
if (d->source != XCAICX_MODULE_ANPR) continue;
if (d->text && d->text[0]) check_against_list(d->text, d->text_score);
else log_plate_seen_but_unread(d->box);
}Add a zone per lane for occupancy and dwell, and the same frames produce throughput reporting with no extra hardware.
5. Night, thermal and IR#
Detection is luma-based and runs on XCAICX_PIX_GRAY8 with no special handling — a thermal or IR stream works.
Careful
PPE compliance does not work on a monochrome sensor. Its helmet and hi-vis tests are colour-ratio tests, and on GRAY8 they have nothing to work with; the result is violations reported indiscriminately. If the site is thermal-only, do not license PPE. Detection, defect inspection and plate localisation are unaffected.
6. Unmanned and remote sites#
Substations, pipeline stations, relay huts, remote border posts.
cfg.license_path = "/etc/xcaicx/unit.token"; /* minted offline, device-bound */
cfg.state_dir = "/var/lib/xcaicx"; /* persistent, survives reboot */
cfg.offline = 1; /* never opens a socket */Build with -DXCAICX_WITH_TLS=OFF and the HTTP client is not linked into the binary at all — a claim the customer's own security team can verify with ldd and strings rather than taking your word for it.
Usage still accrues to state_dir/usage-spool.jsonl for collection on a service visit. See Air-gapped deployment for the provisioning and renewal workflow, and plan the licence term against the site's maintenance schedule rather than the calendar — an annual term on a site reachable once a year gives you a zero-day margin.
7. Sizing and placement, before you install#
The questions that decide whether a deployment works, in the order they bite:
- Pixels on target. At 320px analysis, how tall is a person at the far end of the field of view? Under ~10px and the answer is a different lens or another camera.
- Where does the tracker get its run-up? Boundaries need a few frames of visible approach.
- What is the frame budget? Measure
total_mson the real board with the real model and a busy scene. An empty corridor is cheap and tells you nothing. - Is
state_dirgenuinely persistent? On a read-only rootfs, confirm it is a real writable overlay and not tmpfs — otherwise every reboot re-activates and consumes a unit. - What happens when analytics stop? The video path must keep recording. A camera that stops recording because a licence lapsed is a warranty claim.
8. What this is not#
Do not
- Not a safety interlock. If a machine must stop when someone reaches into it, that is a rated safety controller's job. Analytics inform people.
- Not a targeting or weapons input, and not licensed for use as one.
- Not an identity system. No faces, no biometrics, no re-identification.
- Not accurate out of the box. The reference backend is a deterministic heuristic for bring-up and CI. A fence line at night needs real models validated on your own footage, in your own lighting. Anyone quoting an accuracy figure before seeing your site is quoting you someone else's.
Next#
- Zones, tripwires & events — the event semantics in detail
- Air-gapped deployment — offline provisioning and renewal
- Security & threat model — what to hand a customer's security team
- Performance & tuning — fitting the budget on the real board