Kami Suspicious Person
/install kami-suspicious-person
\r \r
Kami Suspicious Person Detection\r
\r
Detect unregistered face loitering events in sensitive areas. The script runs continuously and outputs an alarm JSON line to stdout each time a stranger exceeds the loiter threshold. It does NOT exit after an alarm — it keeps monitoring. Set run_time: 0 for unlimited operation.\r
\r
Uses ONNX models directly (no insightface package dependency) — works on Linux, macOS, and Windows:\r
- SCRFD (
det_10g.onnx) for face detection + 5-point landmarks\r - ArcFace (
w600k_r50.onnx) for 512-dim face embedding extraction\r \r
How it works\r
\r
- Face detection + landmarks (local, CPU): SCRFD detects faces and extracts 5-point landmarks every
sample_intervalseconds.\r - Face alignment + embedding: ArcFace extracts 512-dim embeddings from aligned 112x112 face crops.\r
- Database matching: Compare embeddings against registered face database via cosine similarity. Registered faces are skipped.\r
- Stranger tracking: Track unregistered faces across frames using embedding sliding average.\r
- Loiter alarm: When a stranger stays longer than
loiter_threshold, output alarm JSON to stdout with face snapshot. After acooldownperiod, the same stranger can trigger again if still present.\r \r
When to Use\r
\r Use this skill when the user wants to:\r
- Monitor a camera feed for unregistered/unknown people\r
- Detect strangers loitering in restricted or sensitive areas\r
- Get real-time alerts when an unknown face stays too long in view\r
- Run continuous face recognition surveillance\r \r
Installation\r
\r
bash setup.sh\r
```\r
\r
This will:\r
1. Detect system Python, create `.venv/` virtual environment\r
2. Install dependencies: `onnxruntime`, `opencv-python-headless`, `numpy`\r
3. Create `alerts/`, `face_db/`, `models/` directories\r
4. Download SCRFD (`det_10g.onnx`) and ArcFace (`w600k_r50.onnx`) models from the insightface release (~180MB total)\r
\r
Idempotent — safe to run repeatedly. Works on Linux and macOS.\r
\r
## Prerequisites\r
\r
- `python3` and `python3-venv` installed on the system\r
- RTSP camera online and network-reachable, OR a local video file for testing\r
- `setup.sh` has been run at least once\r
- (Optional) Registered face images placed in `face_db/\x3Cperson_name>/xxx.jpg`\r
\r
## Face Database Setup\r
\r
Place registered personnel photos in the `face_db/` directory:\r
\r
```\r
face_db/\r
├── Alice/\r
│ ├── photo1.jpg\r
│ └── photo2.jpg\r
├── Bob/\r
│ └── photo1.jpg\r
└── face_db.pkl (auto-generated cache)\r
```\r
\r
To pre-build the database cache:\r
```bash\r
.venv/bin/python build_face_db.py --face_db ./face_db\r
```\r
\r
## Parameter Confirmation\r
\r
Before running this skill, confirm the following parameters with the user:\r
\r
| Parameter | Default | Description |\r
|-----------|---------|-------------|\r
| `--rtsp_url` | *(required)* | RTSP camera URL or local video file path |\r
| `--face_db` | `face_db/` | Registered face database directory |\r
| `--det_model` | `models/det_10g.onnx` | SCRFD face detection model path |\r
| `--rec_model` | `models/w600k_r50.onnx` | ArcFace face recognition model path |\r
| `--db_match_threshold` | `0.4` | Cosine similarity threshold for database matching |\r
| `--stranger_match_threshold` | `0.35` | Cosine similarity threshold for cross-frame stranger tracking |\r
| `--loiter_threshold` | `300` | Loitering alert threshold in seconds (300 = 5 minutes) |\r
| `--sample_interval` | `2.0` | Face detection sampling interval (seconds) |\r
| `--cooldown` | `300` | Per-stranger alert cooldown (seconds); same stranger won't re-alert within this window |\r
| `--det_thresh` | `0.5` | Face detection confidence threshold |\r
| `--min_face_size` | `40` | Minimum face size in pixels |\r
| `--output_dir` | `alerts/` | Alert output directory |\r
| `--run_time` | `0` | Max run time in seconds; `0` = unlimited |\r
| `--fps` | `15` | Video stream frame rate |\r
| `--expire_seconds` | `600` | Stranger tracking expiry (seconds since last seen) |\r
| `--inbox_file` | `alerts/pending.jsonl` | Alarm inbox file consumed by the LLM heartbeat task |\r
| `--feishu_webhook` | *(env `FEISHU_WEBHOOK_URL`)* | Feishu custom bot webhook URL — alarms are pushed directly to the user's phone |\r
| `--feishu_secret` | *(env `FEISHU_WEBHOOK_SECRET`)* | Feishu webhook signing secret (only if the bot has signing enabled) |\r
\r
**Ask the user: do any parameters need to be changed?**\r
\r
### Feishu push setup\r
\r
Create a Feishu custom bot (自定义机器人) in the target group chat, copy its webhook URL, then either:\r
\r
```bash\r
export FEISHU_WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx"\r
# Optional, only if the bot has "签名校验" enabled:\r
export FEISHU_WEBHOOK_SECRET="your_secret_here"\r
```\r
\r
Or pass `--feishu_webhook` / `--feishu_secret` on the CLI. When set, every alarm is POSTed to Feishu as an interactive card (title / stranger_id / duration / timestamp / snapshot path).\r
\r
## Usage\r
\r
```bash\r
# Initialize environment (first time only)\r
bash setup.sh\r
\r
# (Optional) Pre-build face database\r
.venv/bin/python build_face_db.py --face_db ./face_db\r
\r
# Run with RTSP stream\r
.venv/bin/python suspicious_person_detector.py \\r
--rtsp_url rtsp://192.168.1.100/live/stream1\r
\r
# Run with local video file (for testing)\r
.venv/bin/python suspicious_person_detector.py \\r
--rtsp_url /path/to/test_video.mp4\r
\r
# Custom parameters\r
.venv/bin/python suspicious_person_detector.py \\r
--rtsp_url rtsp://192.168.1.100/live/stream1 \\r
--loiter_threshold 60 \\r
--sample_interval 1.0 \\r
--cooldown 120\r
```\r
\r
## Output Format (stdout JSON)\r
\r
The skill runs continuously and prints a JSON alarm line to stdout each time a stranger loitering event is detected. It does NOT stop after an alarm — it resets and keeps monitoring.\r
\r
When alarm triggers:\r
```json\r
{\r
"alarm": true,\r
"type": "stranger_loitering",\r
"timestamp": "2025-01-15T14:30:22.123456",\r
"stranger_id": "STR_0001",\r
"duration_seconds": 312.5,\r
"duration_display": "5m12s",\r
"face_image": "alerts/STR_0001_20250115_143022.jpg",\r
"hit_count": 48,\r
"message": "Warning: Stranger STR_0001 detected loitering in sensitive area for 5m12s, exceeding alert threshold. Face snapshot saved to alerts/STR_0001_20250115_143022.jpg. Please review and take appropriate action."\r
}\r
```\r
\r
When no alarm (normal exit after run_time or stream end):\r
```json\r
{\r
"alarm": false,\r
"type": null,\r
"detail": "No stranger loitering detected",\r
"run_seconds": 3600.0,\r
"source": "rtsp://192.168.1.100/live/stream1"\r
}\r
```\r
\r
## Exit Codes\r
\r
| Code | Meaning |\r
|------|---------|\r
| `0` | Run time exceeded or stream ended (normal exit) |\r
| `1` | Video source failure or runtime error |\r
\r
The skill runs continuously and prints a JSON alarm line to stdout each time a stranger loitering event is detected. It does NOT stop after an alarm — it resets and keeps monitoring. Set `run_time: 0` for unlimited operation.\r
\r
Check `suspicious_person.log` for detailed diagnostics.\r
\r
## Architecture\r
\r
```\r
RTSP/File → FrameGrabber thread (latest frame only)\r
└─ Latest frame → main thread (every sample_interval)\r
├─ insightface: detect faces + extract embeddings\r
├─ FaceDatabase: match against registered faces\r
│ ├─ Registered → skip\r
│ └─ Stranger → StrangerTracker\r
│ ├─ Known stranger → update last_seen, avg embedding\r
│ └─ New stranger → create tracking record\r
└─ Check loiter duration ≥ threshold?\r
├─ No → continue monitoring\r
└─ Yes (and not in cooldown) → print alarm JSON to stdout\r
→ save face snapshot\r
→ continue monitoring (do NOT exit)\r
```\r
\r
## Troubleshooting\r
\r
**Virtual environment not found**\r
→ Run `bash setup.sh`\r
\r
**insightface model download fails**\r
→ Check network connectivity. Model is downloaded to `models/` on first run.\r
\r
**No faces detected**\r
→ Check `--det_thresh` (try lowering to 0.3), ensure faces are large enough (`--min_face_size`), verify camera resolution.\r
\r
**Too many false stranger alerts**\r
→ Increase `--db_match_threshold` (e.g., 0.45), add more photos per person to `face_db/`.\r
\r
**Same stranger triggers repeated alerts**\r
→ Increase `--cooldown` (e.g., 600 for 10-minute cooldown between alerts for the same person).\r
\r
## Strict Rules (MUST Follow)\r
\r
**These rules are mandatory. The agent MUST comply with every rule below without exception.**\r
\r
### 1. Execute Immediately\r
\r
When the user requests stranger loitering detection or monitoring, start the script **immediately** as a background daemon (e.g. `nohup ... &` or a systemd service) so the agent is NOT blocked waiting on a foreground process. Do NOT ask unnecessary follow-up questions if the RTSP URL is already known.\r
\r
### 2. Alarm Delivery Architecture (READ THIS)\r
\r
The detector is a long-running process. The agent CANNOT watch its stdout in real time (a blocking tool call never returns, and the LLM is only invoked on user messages / heartbeats / cron). Therefore alarms are delivered via **two out-of-band channels**:\r
\r
1. **Feishu webhook (instant push to user's phone)** — the script POSTs every alarm to the configured Feishu bot. This guarantees the user sees the event within seconds, regardless of whether the LLM is running.\r
2. **Inbox file `alerts/pending.jsonl` (for LLM context)** — the script appends every alarm here. A heartbeat task defined in `space/HEARTBEAT.md` polls this file and reports unreported alarms to the user.\r
\r
The agent's job is **NOT** to tail stdout. The agent's job is to make sure the heartbeat task in `HEARTBEAT.md` is healthy and that Feishu env vars are set before launching.\r
\r
### 3. Proactively Report on Every Heartbeat\r
\r
On each heartbeat, the agent **MUST** follow `space/HEARTBEAT.md`:\r
\r
- Read `kami-suspicious-person/alerts/pending.jsonl`\r
- If non-empty, send ONE proactive summary message to the user covering each alarm (stranger_id, duration, face_image path, timestamp), then MOVE (not delete) the file to `alerts/consumed/\x3Ctimestamp>.jsonl`\r
- If empty, reply `HEARTBEAT_OK`\r
\r
**Never** reply `HEARTBEAT_OK` on a heartbeat that has unreported alarms.\r
\r
### 4. Launch Checklist\r
\r
Before launching the detector, the agent MUST verify:\r
\r
- [ ] `FEISHU_WEBHOOK_URL` is set (or `--feishu_webhook` is passed). If not, warn the user that phone push is disabled.\r
- [ ] `alerts/` directory is writable.\r
- [ ] `space/HEARTBEAT.md` still contains the stranger-alert inbox task.\r
- [ ] The previous run's `alerts/pending.jsonl` has been consumed (or archive it before starting, to avoid re-reporting stale alarms).\r
\r
### 5. Auto-Restart After Script Exits\r
\r
If the script exits, check the exit code:\r
- Exit `0`: normal end. Tell the user and ask if they want to restart.\r
- Exit `1`: error. Report the error (include tail of `suspicious_person.log`).\r
- If the user requested continuous monitoring, restart the script automatically without asking.\r
\r
### 6. Summary\r
\r
```\r
RULE: Alarms flow via (a) Feishu webhook (script → user) and (b) inbox file (script → heartbeat → user). Never rely on tailing stdout.\r
RULE: Every heartbeat consumes alerts/pending.jsonl; non-empty → proactive message; empty → HEARTBEAT_OK.\r
RULE: Consumed alarms are MOVED to alerts/consumed/, not deleted.\r
RULE: Launch the detector as a background daemon so the agent is never blocked.\r
RULE: Verify FEISHU_WEBHOOK_URL before launch; warn if missing.\r
```\r
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install kami-suspicious-person - After installation, invoke the skill by name or use
/kami-suspicious-person - Provide required inputs per the skill's parameter spec and get structured output
What is Kami Suspicious Person?
Detect unregistered faces loitering in sensitive areas. Runs continuously, outputs alarm JSON to stdout each time a stranger exceeds the loiter threshold, th... It is an AI Agent Skill for Claude Code / OpenClaw, with 43 downloads so far.
How do I install Kami Suspicious Person?
Run "/install kami-suspicious-person" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Kami Suspicious Person free?
Yes, Kami Suspicious Person is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Kami Suspicious Person support?
Kami Suspicious Person is cross-platform and runs anywhere OpenClaw / Claude Code is available (linux).
Who created Kami Suspicious Person?
It is built and maintained by KamiVision (@13681882136); the current version is v1.0.0.