The problem was not simply detecting an object

Video systems can capture faces, people, license plates, documents, and other identifying context. Sending every raw frame to a cloud inference service may be unnecessary or unsuitable for some deployments. I wanted a component that could run near the source, use a compatible local model, and mask selected detected regions before downstream use.

Local processing changes where inference happens. It does not make the complete system private by definition. Raw frames still enter device memory, detections can fail, other identifiers can remain, and the surrounding application may still store or transmit data. That boundary is central to how PrivacyGuard should be described.

What I built

I built PrivacyGuard independently as one component inside a larger CCTV system for a freelance client. It has been used with real footage, but the client, recordings, private infrastructure, and operational details remain confidential.

The public repository is the inspectable component, not the client system. It covers image files, recorded video, camera and stream inputs, a Python API, a command-line interface, and optional helpers for batch processing, operation logging, runtime monitoring, and fixed-region masking.

  • Detection: run a compatible ONNX object-detection model and decode supported output formats.
  • Selection: filter detections using configured labels, target classes, confidence, and overlap thresholds.
  • Masking: apply Gaussian blur, pixelation, or solid fill to detected regions.
  • Integration: return processed frames or write image and video outputs for a surrounding application.

Faces, people, or license plates are not capabilities created by the masking code alone. The selected model must actually support the intended classes, and its label mapping must match the application configuration.

The pipeline is deliberately separable

The core flow is straightforward:

  1. Read a frame from an image, video file, camera, or stream.
  2. Prepare the frame for the configured ONNX model.
  3. Run inference and convert supported model output into detections.
  4. Apply confidence filtering and class-aware overlap suppression.
  5. Mask the selected regions using the configured method.
  6. Return, display, or write the processed frame.

Detection and masking are separate because they answer different questions. Detection asks where a configured model believes a target exists. Masking decides how to modify that region. Keeping them separate makes it possible to inspect detections, choose different treatments by class, add padding, or integrate the component into a larger workflow.

Masking methods are operational choices, not privacy levels

PrivacyGuard exposes three treatments:

  • Gaussian blur reduces visible detail while retaining some scene context.
  • Pixelation replaces a region with a coarse block representation.
  • Solid fill covers the selected region completely.

None of these methods repairs a missed detection. Blur and pixelation are not encryption, and even a solid region does not remove identifiers elsewhere in a frame, its metadata, its audio, or related records. The right configuration depends on the threat model and must be evaluated against representative footage.

What the 25–30 FPS result means

A historical controlled internal run reached approximately 25–30 FPS. That is the narrowest supportable wording.

The retained repository and project history do not preserve a signed-off benchmark record containing the exact hardware, model artifact and hash, ONNX Runtime provider, source footage, warm-up, measured frame count, masking configuration, output encoding, and pipeline stages included in timing. The result therefore should not be attributed to Raspberry Pi 4, a $35 computer, every YOLOv8-nano model, or an arbitrary deployment.

Performance varies with hardware, runtime provider, model architecture and input size, source resolution and codec, number and size of detected regions, masking method, display, and output encoding. A useful benchmark must freeze those variables and report latency distribution and dropped frames—not only one FPS number.

Throughput also says nothing about detection quality. A fast pipeline that misses small, distant, occluded, or out-of-distribution targets is not successful merely because it processes frames quickly.

A technical control is not a legal conclusion

Running detection locally can reduce reliance on a cloud inference API and can limit which visual information is released downstream. Those are useful engineering properties. They do not establish that output is anonymous or that a deployment complies with GDPR, CCPA, or another legal framework.

Legal and operational outcomes depend on the complete processing system: purpose, lawful basis, notices, access controls, storage, retention, deletion, security, contracts, human review, incident handling, and the possibility of identification from remaining context. Operation logs show that software events were recorded; they do not prove that every sensitive region was detected or that a legal obligation was satisfied.

The practical rule is simple: describe the technical behavior precisely, evaluate identifiability and detection failures in context, and obtain qualified advice for the actual deployment.

Current publication boundary

  • The public code is an independent component released under the MIT License.
  • It has been used with real footage as part of a larger confidential CCTV project.
  • The public repository is not the complete client system and does not expose client data or infrastructure.
  • Experimental regional text, document, and plate modules require compatible models and deployment-specific validation.
  • The project is not presented as automatic legal compliance, guaranteed anonymity, or a universal performance benchmark.

The engineering lesson

The difficult part of privacy-oriented computer vision is not adding blur to a rectangle. It is defining what must be detected, measuring false negatives under realistic conditions, choosing what happens when confidence is low, controlling the data around the model, and preserving enough evidence to explain what was actually tested.

PrivacyGuard demonstrates the component-level engineering: ONNX inference, configurable detection and masking, stream and file workflows, and integration helpers. The larger responsibility is knowing where that component ends.

Code and references

The canonical PrivacyGuard case study summarizes the project, deployment context, public evidence, and current limitations.