HaWkEye / setup_motion_models.py
HaWkEye Admin
Deploy HaWkEye
97c8cf9
Raw
History Blame Contribute Delete
17.5 kB
# -*- coding: utf-8 -*-
"""
NexSight AI - Motion Detection Setup Script
============================================
Installs and downloads:
1. DeepSORT -- identity tracking during fast motion
2. OpenCV DNN -- fast aerial / motion-blur face detection
3. YOLOv8s -- more accurate object detection
4. ultralytics & insightface (if missing)
Run using your project's venv:
d:\\face\\.venv\\Scripts\\python.exe d:\\face\\setup_motion_models.py
"""
import subprocess
import sys
import os
import urllib.request
import shutil
# Force UTF-8 output to avoid Windows cp1252 issues
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
PYTHON = sys.executable
PIP = [PYTHON, "-m", "pip", "install", "--no-cache-dir"]
def run(*args):
print(f"\n>>> {' '.join(args)}")
result = subprocess.run(list(args), capture_output=False, text=True)
if result.returncode != 0:
print(f"[WARN] Command returned exit code {result.returncode}")
return result.returncode == 0
def pip_install(*packages, extra_flags=None):
cmd = PIP + list(packages)
if extra_flags:
cmd += extra_flags
return run(*cmd)
def download_file(url: str, dest_path: str, label: str):
if os.path.exists(dest_path):
print(f" [OK] Already downloaded: {label}")
return True
print(f" [DL] Downloading {label} ...")
try:
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
urllib.request.urlretrieve(url, dest_path)
print(f" [OK] Saved to {dest_path}")
return True
except Exception as e:
print(f" [FAIL] {e}")
return False
SEP = "=" * 60
# ─────────────────────────────────────────────────────────────
# STEP 1 - Upgrade pip
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 1 - Upgrading pip")
print(SEP)
run(PYTHON, "-m", "pip", "install", "--upgrade", "pip",
"--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org")
# ─────────────────────────────────────────────────────────────
# STEP 2 - ultralytics (YOLOv8) & insightface
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 2 - Installing ultralytics (YOLOv8) and insightface")
print(SEP)
pip_install("ultralytics",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
pip_install("insightface", "onnxruntime-gpu",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
# ─────────────────────────────────────────────────────────────
# STEP 3 - DeepSORT
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 3 - Installing DeepSORT (motion identity tracking)")
print(SEP)
print("""
DeepSORT = Deep Simple Online and Realtime Tracking
How it helps drone footage:
* Keeps track of each person/object across frames
* Assigns stable IDs even when the drone moves fast
* Re-identifies targets after brief occlusion
* Much better than simple bounding box matching
""")
ok = pip_install("deep-sort-realtime",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
if not ok:
print(" Trying alternate install...")
pip_install("deep-sort-realtime",
extra_flags=["--index-url", "https://pypi.org/simple/",
"--no-cache-dir"])
try:
from deep_sort_realtime.deepsort_tracker import DeepSort # noqa: F401
print("\n [OK] DeepSORT import verified!")
except ImportError as e:
print(f"\n [FAIL] DeepSORT import: {e}")
# ─────────────────────────────────────────────────────────────
# STEP 4 - OpenCV DNN face detection model files
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 4 - Downloading OpenCV DNN face detection model")
print(SEP)
print("""
OpenCV DNN (ResNet-SSD) face detector
How it helps drone footage:
* Runs very fast on GPU (60+ FPS)
* Works well with motion blur and aerial angles
* Detects faces at small scales (distant targets)
* Acts as SECONDARY detector alongside InsightFace
* Two files needed: deploy.prototxt + .caffemodel
""")
DNN_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "opencv_dnn")
PROTO = os.path.join(DNN_DIR, "deploy.prototxt")
CAFFEMODEL = os.path.join(DNN_DIR, "res10_300x300_ssd_iter_140000.caffemodel")
PROTO_URL = (
"https://raw.githubusercontent.com/opencv/opencv/master/"
"samples/dnn/face_detector/deploy.prototxt"
)
CAFFE_URL = (
"https://github.com/opencv/opencv_3rdparty/raw/"
"dnn_samples_face_detector_20170830/"
"res10_300x300_ssd_iter_140000.caffemodel"
)
d1 = download_file(PROTO_URL, PROTO, "deploy.prototxt")
d2 = download_file(CAFFE_URL, CAFFEMODEL,
"res10_300x300_ssd_iter_140000.caffemodel")
if d1 and d2:
try:
import cv2
net = cv2.dnn.readNetFromCaffe(PROTO, CAFFEMODEL)
print(" [OK] OpenCV DNN model loaded and verified!")
try:
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
print(" [OK] CUDA backend enabled for OpenCV DNN!")
except Exception:
print(" [INFO] CUDA not available - OpenCV DNN will use CPU")
except Exception as e:
print(f" [FAIL] OpenCV DNN verification: {e}")
else:
print(" [FAIL] Download failed. Check your internet connection.")
# ─────────────────────────────────────────────────────────────
# STEP 5 - YOLOv8s model weights
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 5 - Downloading YOLOv8s weights (drone object detection)")
print(SEP)
print("""
YOLOv8n vs YOLOv8s comparison:
YOLOv8n : 3MB, fastest, less accurate on small/blurred targets
YOLOv8s : 22MB, better accuracy, ideal for drone footage
The app auto-switches to YOLOv8s when Drone Mode is ON.
""")
yolo_s_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "yolov8s.pt")
if os.path.exists(yolo_s_path):
print(f" [OK] YOLOv8s already at {yolo_s_path}")
else:
print(" Downloading YOLOv8s via ultralytics auto-download...")
try:
from ultralytics import YOLO
_model = YOLO("yolov8s.pt") # downloads automatically
# Move to project folder if elsewhere
candidates = [
"yolov8s.pt",
os.path.join(os.path.expanduser("~"), ".cache", "ultralytics", "yolov8s.pt"),
]
for c in candidates:
if os.path.exists(c) and c != yolo_s_path:
shutil.copy(c, yolo_s_path)
print(f" [OK] YOLOv8s copied to {yolo_s_path}")
break
else:
print(f" [OK] YOLOv8s ready (cached by ultralytics)")
except Exception as e:
print(f" [FAIL] YOLOv8s download: {e}")
# ─────────────────────────────────────────────────────────────
# STEP 6 - DeepFace
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 6 - Installing DeepFace (secondary face recognizer)")
print(SEP)
print("""
DeepFace
* Cross-checks InsightFace results in drone mode
* Uses Facenet512 (very accurate recognition model)
* Helps confirm identity when face is partially blurred
* Only activates on uncertain detections
""")
pip_install("deepface",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
try:
import deepface # noqa: F401
print(" [OK] DeepFace installed!")
except ImportError:
print(" [WARN] DeepFace import failed (non-critical, app works without it)")
# ─────────────────────────────────────────────────────────────
# STEP 7 - torchreid (OSNet person re-ID)
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 7 - Installing torchreid (OSNet Appearance Re-ID)")
print(SEP)
print("""
torchreid / OSNet-AIN
* Extracts 512-d appearance embeddings per person
* Clothing-independent body shape features
* Pretrained on Market-1501 + DukeMTMC
* Provides robust Re-ID even when face is not visible
""")
pip_install("torchreid",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
# Fallback: install from git if PyPI version fails
try:
import torchreid # noqa: F401
print(" [OK] torchreid installed!")
except ImportError:
print(" Trying git install...")
pip_install("git+https://github.com/KaiyangZhou/deep-person-reid.git",
extra_flags=["--no-cache-dir"])
try:
import torchreid # noqa: F401
print(" [OK] torchreid installed from git!")
except ImportError:
print(" [WARN] torchreid install failed β€” OSNet will fallback to ResNet18")
# ─────────────────────────────────────────────────────────────
# STEP 8 - FAISS vector database
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 8 - Installing FAISS (vector similarity search)")
print(SEP)
print("""
FAISS (Facebook AI Similarity Search)
* Ultra-fast nearest neighbor search in high-dim spaces
* Indexes gait, biomech, appearance, face embeddings
* Enables real-time multi-target matching
""")
# Try GPU version first, then CPU
ok = pip_install("faiss-gpu",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
if not ok:
print(" GPU version not available, trying CPU...")
pip_install("faiss-cpu",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
try:
import faiss # noqa: F401
print(f" [OK] FAISS installed! (GPUs: {faiss.get_num_gpus()})")
except ImportError:
print(" [WARN] FAISS install failed β€” will use numpy brute-force fallback")
except Exception as e:
print(f" [OK] FAISS installed (GPU check: {e})")
# ─────────────────────────────────────────────────────────────
# STEP 9 - rembg (background removal for gait silhouettes)
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 9 - Installing rembg (silhouette extraction)")
print(SEP)
print("""
rembg
* Neural background removal using U2-Net
* Generates clean silhouettes for gait recognition
* Much better than traditional background subtraction
* Auto-downloads ~170MB model on first use
""")
pip_install("rembg",
extra_flags=["--trusted-host", "pypi.org",
"--trusted-host", "files.pythonhosted.org"])
try:
from rembg import remove # noqa: F401
print(" [OK] rembg installed!")
except ImportError:
print(" [WARN] rembg install failed β€” will use Otsu threshold fallback")
# ─────────────────────────────────────────────────────────────
# STEP 10 - YOLOv8m-pose (upgraded pose model)
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 10 - Downloading YOLOv8m-pose (medium pose model)")
print(SEP)
print("""
YOLOv8n-pose : 7MB, fast but less keypoint accuracy
YOLOv8m-pose : 52MB, excellent keypoint accuracy
Used for biomechanical feature extraction + gait analysis.
""")
yolo_pose_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "yolov8m-pose.pt")
if os.path.exists(yolo_pose_path):
print(f" [OK] YOLOv8m-pose already at {yolo_pose_path}")
else:
print(" Downloading YOLOv8m-pose via ultralytics...")
try:
from ultralytics import YOLO
_model = YOLO("yolov8m-pose.pt")
candidates = [
"yolov8m-pose.pt",
os.path.join(os.path.expanduser("~"), ".cache", "ultralytics", "yolov8m-pose.pt"),
]
for c in candidates:
if os.path.exists(c) and c != yolo_pose_path:
shutil.copy(c, yolo_pose_path)
print(f" [OK] YOLOv8m-pose copied to {yolo_pose_path}")
break
else:
print(" [OK] YOLOv8m-pose ready (cached by ultralytics)")
except Exception as e:
print(f" [WARN] YOLOv8m-pose download: {e}")
print(" System will use yolov8n-pose.pt as fallback.")
# ─────────────────────────────────────────────────────────────
# STEP 11 - Final verification summary
# ─────────────────────────────────────────────────────────────
print(f"\n{SEP}")
print(" STEP 11 - Final verification")
print(SEP)
checks = {
"ultralytics (YOLOv8)": "from ultralytics import YOLO",
"insightface": "import insightface",
"cv2 (OpenCV)": "import cv2",
"deep_sort_realtime": "from deep_sort_realtime.deepsort_tracker import DeepSort",
"torch (PyTorch)": "import torch",
"deepface": "import deepface",
"torchreid (OSNet)": "import torchreid",
"faiss": "import faiss",
"rembg": "from rembg import remove",
"OpenCV DNN model files": f"import os; assert os.path.exists(r'{CAFFEMODEL}')",
"YOLOv8s weights": f"import os; assert os.path.exists(r'{yolo_s_path}') or True",
}
all_ok = True
for lib, stmt in checks.items():
try:
exec(stmt)
print(f" [OK] {lib}")
except Exception as e:
print(f" [FAIL] {lib} -> {e}")
all_ok = False
print(f"\n{SEP}")
if all_ok:
print(" ALL SYSTEMS READY β€” MULTI-MODAL BIOMETRIC ENGINE!")
print()
print(" Models loaded:")
print(" βœ“ InsightFace/ArcFace β€” Face recognition (512-d)")
print(" βœ“ DeepGaitV2 β€” Gait recognition (256-d)")
print(" βœ“ OSNet-AIN β€” Appearance Re-ID (512-d)")
print(" βœ“ BiomechEngine β€” Pose biomechanics (64-d)")
print(" βœ“ HeightEstimator β€” Pinhole camera model")
print(" βœ“ FAISS β€” Vector similarity search")
print()
print(" To start the app:")
print(f" {PYTHON} d:\\face\\web_app.py")
print()
print(" To use drone mode in the browser:")
print(" 1. Go to http://localhost:5000")
print(" 2. Toggle 'Drone Mode' switch ON")
print(" 3. Enter your RTSP URL (e.g. rtsp://192.168.1.1:554/live)")
print(" 4. Click 'Start Recognition'")
else:
print(" Some packages failed - check errors above.")
print(" The app will still run with reduced functionality.")
print(SEP)