{"id":51732792,"url":"https://github.com/dejely/privmotion","last_synced_at":"2026-07-18T03:18:50.229Z","repository":{"id":362465328,"uuid":"1257284926","full_name":"dejely/privmotion","owner":"dejely","description":"Privacy-preserving motion analytics for videos, RGB-D streams, and frame folders.","archived":false,"fork":false,"pushed_at":"2026-06-04T09:42:39.000Z","size":3403,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-04T11:11:47.534Z","etag":null,"topics":["computer-vision","depth-est","motion-analysis","pose-estimation","privacy","skeleton","surrogate-model","video-analytics"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dejely.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":"THREAT_MODEL.md","audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-02T14:32:55.000Z","updated_at":"2026-06-04T09:42:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dejely/privmotion","commit_stats":null,"previous_names":["dejely/privmotion"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dejely/privmotion","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dejely%2Fprivmotion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dejely%2Fprivmotion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dejely%2Fprivmotion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dejely%2Fprivmotion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dejely","download_url":"https://codeload.github.com/dejely/privmotion/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dejely%2Fprivmotion/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35603072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-18T02:00:07.223Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computer-vision","depth-est","motion-analysis","pose-estimation","privacy","skeleton","surrogate-model","video-analytics"],"created_at":"2026-07-18T03:18:49.520Z","updated_at":"2026-07-18T03:18:50.217Z","avatar_url":"https://github.com/dejely.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# privmotion\n\nPrivacy-preserving motion analytics for videos, RGB-D streams, and frame folders.\n\n\u003e [!NOTE]\n\u003e `privmotion` is a runnable research prototype and OpenCV-contrib-style module\n\u003e scaffold. It is not an official OpenCV module, and it is not a production\n\u003e privacy guarantee. Its HIPAA-oriented mode supports expert review; it does\n\u003e not certify HIPAA de-identification by itself.\n\n`privmotion` transforms identity-bearing visual input into anonymized kinematic\nartifacts: skeletons, silhouettes, depth-like surrogates, feature records,\nbenchmark reports, and GIF/MP4 previews. Raw RGB is used only in memory for\nprocessing and is not written to outputs by default.\n\n[![Python](https://img.shields.io/badge/python-3.10%2B-blue)](pyproject.toml)\n[![License](https://img.shields.io/badge/license-Apache--2.0-green)](LICENSE)\n[![YOLO Pose](https://img.shields.io/badge/YOLO--Pose-optional-orange)](#yolo-pose)\n[![OpenCV Scaffold](https://img.shields.io/badge/OpenCV--style-scaffold-lightgrey)](#opencv-style-scaffold)\n\n## Table of Contents\n\n- [What is privmotion?](#what-is-privmotion)\n- [Demo](#demo)\n- [Quick Start](#quick-start)\n- [Key Capabilities](#key-capabilities)\n- [Output Artifacts](#output-artifacts)\n- [Encrypted Feature Controls](#encrypted-feature-controls)\n- [HIPAA Expert-Ready Aggregate Mode](#hipaa-expert-ready-aggregate-mode)\n- [Privacy and Security Docs](#privacy-and-security-docs)\n- [Architecture](#architecture)\n- [Dataset Evaluation](#dataset-evaluation)\n- [OpenCV-Style Scaffold](#opencv-style-scaffold)\n- [Development](#development)\n- [Privacy Scope and Limitations](#privacy-scope-and-limitations)\n- [License](#license)\n\n## What is privmotion?\n\n`privmotion` is a prototype toolkit for privacy-preserving kinematic analytics.\nIt accepts image files, MP4 files, and directories of frames, then exports\nmachine-readable motion data without saving the original RGB frames.\n\nThe goal is to make motion analysis inspectable without exposing the source\nvideo by default. A typical run produces skeleton keypoints, silhouette masks,\nlow-resolution depth-like surrogates, simple kinematic features, validation\nreports, and an anonymized preview render.\n\n## Demo\n\n\u003cp align='center'\u003e\n  \u003cimg src=\"assets/preview.gif\" alt=\"privmotion demo\" width='100%'\u003e\n\u003cp\u003e\n\nSample privmotion demo.\n\nGenerate a local anonymized preview:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.process \\\n  --input examples/videoplayback.mp4 \\\n  --output out/demo \\\n  --mode skeleton,silhouette,depth-surrogate,features\n\nPYTHONPATH=src python -m privmotion.cli.visualize \\\n  --output out/demo \\\n  --visualization assets/preview.mp4 \\\n  --fps 8 \\\n  --size 1280x720\n```\n\nFor a GIF preview instead:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.visualize \\\n  --output out/demo \\\n  --visualization assets/preview.gif \\\n  --fps 6 \\\n  --size 960x540\n```\n\nThe visualizer reads anonymized outputs only. It does not reload or display the\noriginal raw video.\n\n## Quick Start\n\n### Install\n\n```bash\npython -m pip install -e .\n```\n\n### YOLO Pose\n\nInstall optional YOLO-Pose support:\n\n```bash\npython -m pip install -e \".[pose]\"\n```\n\nWith `--pose-backend auto`, `privmotion` tries YOLO-Pose when Ultralytics is\ninstalled and falls back to the deterministic prototype backend when it is not.\nYOLO may download model weights such as `yolo11n-pose.pt` on first use. Model\nweights are ignored by git.\n\n### Process a Video\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.process \\\n  --input examples/videoplayback.mp4 \\\n  --output out/video_run \\\n  --mode skeleton,silhouette,depth-surrogate,features\n```\n\nForce YOLO-Pose:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.process \\\n  --input examples/videoplayback.mp4 \\\n  --output out/video_yolo \\\n  --mode skeleton,silhouette,depth-surrogate,features \\\n  --pose-backend yolo \\\n  --pose-model yolo11n-pose.pt\n```\n\nForce the lightweight prototype backend:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.process \\\n  --input examples/videoplayback.mp4 \\\n  --output out/video_prototype \\\n  --mode skeleton,silhouette,depth-surrogate,features \\\n  --pose-backend prototype\n```\n\n### Validate and Render\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.validate \\\n  --output out/video_run\n\nPYTHONPATH=src python -m privmotion.cli.visualize \\\n  --output out/video_run \\\n  --visualization out/video_run/preview.mp4 \\\n  --fps 8 \\\n  --size 1280x720\n```\n\n### Benchmark\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.benchmark \\\n  --output out/video_run \\\n  --report out/video_run/benchmark_report.json\n```\n\n## Key Capabilities\n\n- **No raw RGB retention by default**: source frames are used in memory and are\n  not copied into the output directory.\n- **Anonymized motion export**: skeletons, masks, depth surrogates, and feature\n  records are saved as machine-readable artifacts.\n- **Opt-in encrypted features**: Phase 5 can encrypt kinematic feature records\n  with a Fernet key, access policy, and audit log while keeping raw RGB\n  unrecoverable by default.\n- **Expert-ready aggregate mode**: a HIPAA-oriented profile writes aggregate\n  reports only and requires qualified Expert Determination review before any\n  de-identification claim.\n- **YOLO-first pose path**: `auto` uses YOLO-Pose when available and records any\n  fallback reason in `metadata.json`.\n- **Person-constrained silhouettes**: YOLO person detections can constrain mask\n  output so silhouettes are not full-scene foreground by default.\n- **Portable previews**: visualizations render to GIF or MP4 from anonymized\n  artifacts.\n- **Local benchmark harness**: deterministic proxy metrics report utility,\n  privacy-retention status, and systems output size.\n- **Manifest evaluation**: batch-process local datasets and aggregate per-sample\n  metrics without downloading external datasets.\n- **OpenCV-style scaffold**: C++ headers, CMake, docs, samples, and source-level\n  tests define a future OpenCV-contrib module shape.\n\n## Output Artifacts\n\nA processed run writes a directory like this:\n\n```text\nout/video_run/\n  metadata.json\n  skeletons.json\n  features.json\n  access_policy.json\n  audit_log.jsonl\n  retention_report.json\n  benchmark_report.json\n  preview.mp4\n  silhouettes/\n  depth_surrogates/\n```\n\nImportant metadata fields:\n\n| Field | Meaning |\n| --- | --- |\n| `backends.requested_pose_backend` | Backend requested by the user. |\n| `backends.pose` | Backend actually used for pose extraction. |\n| `backends.pose_model` | Selected pose model when YOLO is used. |\n| `backends.pose_fallback_reason` | Reason `auto` fell back, if it did. |\n| `feature_encryption.mode` | `none` by default, or `fernet` for encrypted feature records. |\n| `feature_encryption.policy_id` | Access policy ID when encrypted features are enabled. |\n| `deidentification_profile` | `standard` by default, or `hipaa-expert-aggregate` for aggregate expert-review outputs. |\n| `retention.raw_rgb_written` | Should remain `false` for default runs. |\n\n## Encrypted Feature Controls\n\nopt-in encrypted **feature records only**. It does not make raw RGB,\nskeletons, silhouettes, depth surrogates, or previews recoverable.\n\nGenerate a Fernet key:\n\n```bash\npython - \u003c\u003c'PY'\nfrom cryptography.fernet import Fernet\nprint(Fernet.generate_key().decode(\"ascii\"))\nPY\n```\n\nExport the key before processing:\n\n```bash\nexport PRIVMOTION_RECOVERY_KEY=\"\u003cgenerated-fernet-key\u003e\"\n```\n\nCreate an access policy JSON, for example:\n\n```json\n{\n  \"policy_id\": \"demo-policy\",\n  \"allowed_purposes\": [\"research-review\"],\n  \"requires_audit\": true\n}\n```\n\nProcess with encrypted feature records:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.process \\\n  --input examples/videoplayback.mp4 \\\n  --output out/video_encrypted \\\n  --mode skeleton,silhouette,depth-surrogate,features \\\n  --feature-encryption fernet \\\n  --access-policy policies/demo-policy.json \\\n  --audit-actor local-operator \\\n  --audit-purpose research-review\n```\n\nInspect encrypted recovery-policy metadata without decrypting records:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.recovery_inspect \\\n  --output out/video_encrypted \\\n  --audit-actor reviewer \\\n  --audit-purpose policy-check\n```\n\nEncrypted runs write `features.json` with `encrypted_records`,\n`access_policy.json`, and `audit_log.jsonl`. There is no decryption CLI in this\nphase.\n\n## HIPAA Expert-Ready Aggregate Mode\n\nHIPAA de-identification under the Privacy Rule requires either Expert\nDetermination or Safe Harbor. The `hipaa-expert-aggregate` profile is designed\nto support the Expert Determination route described by HHS; it does not make an\nautomatic legal or compliance claim.\n\nRun aggregate-only processing:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.process \\\n  --input examples/videoplayback.mp4 \\\n  --output out/hipaa_aggregate \\\n  --deidentification-profile hipaa-expert-aggregate \\\n  --mode aggregate\n```\n\nValidate the aggregate output:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.validate \\\n  --output out/hipaa_aggregate \\\n  --deidentification-profile hipaa-expert-aggregate\n```\n\nHIPAA aggregate runs write only:\n\n```text\nout/hipaa_aggregate/\n  metadata.json\n  aggregate_report.json\n  deidentification_report.json\n  retention_report.json\n```\n\nThis mode does not write skeletons, features, silhouettes, depth surrogates,\npreviews, frame PNGs, exact frame timestamps, source filenames, paths, track\nIDs, boxes, centroids, keypoints, or velocities. `privmotion-visualize` and\n`privmotion-benchmark` reject these outputs because rendering or benchmark\nreports would create path, timestamp, or person-level artifacts.\n\nHHS guidance: \u003chttps://www.hhs.gov/hipaa/for-professionals/privacy/special-topics/de-identification/\u003e.\n\n## Privacy and Security Docs\n\nUse these documents when evaluating whether `privmotion` is appropriate for a\ndataset, demo, research workflow, or regulated environment:\n\n- [PRIVACY_MODEL.md](PRIVACY_MODEL.md): explains what enters the system, what is\n  stored or discarded, what privacy level the tool provides, and what it does\n  not guarantee.\n- [DATA_RETENTION.md](DATA_RETENTION.md): defines the `no-raw-rgb` retention\n  policy, generated artifact lifecycle, deletion guidance, and demo media rules.\n- [THREAT_MODEL.md](THREAT_MODEL.md): documents assets, trust boundaries, abuse\n  paths, risks, and mitigations for the current CLI/library prototype.\n\n## Architecture\n\n```text\nRGB / RGB-D / video input\n        |\n        v\nframe ingest\n        |\n        v\nperson detection or segmentation\n        |\n        v\nappearance suppression\n        |\n        +--\u003e skeleton export\n        +--\u003e silhouette export\n        +--\u003e depth surrogate export\n        +--\u003e feature records\n        +--\u003e aggregate-only expert-review report\n        |\n        v\nretention validation + benchmark reports + anonymized preview\n```\n\nThe Python implementation is the runnable path today. The C++ scaffold mirrors\nthe same concepts for future OpenCV-style integration.\n\n## Dataset Evaluation\n\nCreate a local manifest:\n\n```json\n{\n  \"samples\": [\n    {\n      \"id\": \"walk_001\",\n      \"input\": \"videos/walk_001.mp4\",\n      \"label\": \"walk\",\n      \"split\": \"test\",\n      \"expected_frames\": 120\n    }\n  ]\n}\n```\n\nRun evaluation:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.dataset_eval \\\n  --manifest datasets/demo_manifest.json \\\n  --output out/dataset_eval \\\n  --visualize \\\n  --visualization-ext .mp4\n```\n\nThis writes per-sample process, validation, benchmark, and optional preview\noutputs, plus:\n\n```text\nout/dataset_eval/dataset_report.json\n```\n\nThe current evaluator uses deterministic local proxy metrics. ORPose-Depth,\nMarket-1501-style re-identification datasets, and consented custom video remain\nfuture dataset integrations.\n\nFor HIPAA-oriented aggregate evaluation, use `--mode aggregate` and\n`--deidentification-profile hipaa-expert-aggregate`. This writes aggregate\ndataset metrics only and rejects `--visualize`.\n\n## OpenCV-Style Scaffold\n\nThe repo includes a Phase 4 scaffold under:\n\n```text\nmodules/privmotion/\n```\n\nIt contains:\n\n- `CMakeLists.txt`\n- public OpenCV-style headers\n- dependency-light C++ stubs\n- a C++ sample\n- source-level smoke tests\n- module documentation\n\nThe scaffold defines future API concepts such as\n`cv::privmotion::AnonymizationConfig`,\n`cv::privmotion::KinematicFrame`, `cv::privmotion::PrivacyReport`,\n`cv::privmotion::UtilityReport`, and\n`cv::privmotion::PrivMotionPipeline`.\n\n## Development\n\nRun the test suite:\n\n```bash\npython -m pytest\n```\n\nUseful CLI help commands:\n\n```bash\nPYTHONPATH=src python -m privmotion.cli.process --help\nPYTHONPATH=src python -m privmotion.cli.validate --help\nPYTHONPATH=src python -m privmotion.cli.visualize --help\nPYTHONPATH=src python -m privmotion.cli.benchmark --help\nPYTHONPATH=src python -m privmotion.cli.dataset_eval --help\nPYTHONPATH=src python -m privmotion.cli.recovery_inspect --help\n```\n\nLocal generated files are ignored through `.gitignore`, including `out/`,\n`outputs/`, virtual environments, install metadata, YOLO weights, and the longer\nlocal planning reference `README.local.md`.\n\n## Privacy Scope and Limitations\n\n\u003e [!WARNING]\n\u003e Anonymized motion artifacts can still leak identity through gait, body shape,\n\u003e silhouette geometry, rare motion patterns, or downstream model behavior.\n\nCurrent limitations:\n\n- This is a prototype, not a production privacy guarantee.\n- YOLO-Pose improves skeleton placement but can still miss people or misplace\n  keypoints.\n- The prototype backend is deterministic and useful for testing, but it is not a\n  real pose model.\n- Benchmarks are local deterministic proxies, not full face recognition,\n  person re-identification, gait leakage, or reconstruction-risk evaluations.\n- Phase 5 encrypts feature records only; it does not recover raw RGB or decrypt\n  records from the CLI.\n- The HIPAA aggregate profile is for Expert Determination support only. A\n  qualified expert still has to determine and document that re-identification\n  risk is very small for the expected recipient and context.\n- Raw RGB is not saved by default, but users still need consent-oriented data\n  policies when processing real people.\n\n## License\n\nApache License 2.0. See [`LICENSE`](LICENSE).\n\n## Contributing\n\nContributions are welcome!\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdejely%2Fprivmotion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdejely%2Fprivmotion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdejely%2Fprivmotion/lists"}