No description
  • Python 97.1%
  • Jupyter Notebook 2.9%
Find a file
silveira256bits 09f14f5eb8 Merge: une local (panorama360 + calibrate_interactive rework + .claude) com remote (lane pipeline + ByteTrack + AVM2 TPS + lane_model)
Reconciliação de branches divergentes:
- Local 8601aff: panorama360.py novo, calibrate_interactive reworked com video
  loading + modos fisheye360 e pano360 + _gpu_warp com OpenCL, .claude config.
- Remote 29ba0ad: lane training pipeline (active_learning, build_lane_dataset,
  train_lane_model, train_colab.ipynb, lane_classical, lane_model_infer),
  lane_pipeline + curvature HUD em openpilot, ByteTrack vehicle tracking,
  AVM2 12-vertex TPS, drivable overlay nos thumbnails, perf fixes (skip
  lane_model em AVM, fix dessync visual das sides).

Conflitos resolvidos:
- avm2_render.py: ficou com a versão do origin (variável `contribution`
  necessária pro cache de warp adicionado em d973f43).
- calibrate_interactive.py: 13 conflitos, todos ficaram com HEAD por ser
  superset funcional. Funções `_tps_warp_image`/`_tps_warp_image_fast` do
  origin foram descartadas — o render do HEAD usa `_gpu_warp` (TPS via UMat
  OpenCL) que é evolução das mesmas. Mantidos: render_fisheye360, render_pano360,
  load_video_frame/step_video_frame, get_pano_world_vecs/get_fisheye_world_vecs,
  adjust_pano/adjust_blend/reset_pano_cam, invalidação seletiva de warp_cache.
- main.py: auto-merge limpo (sem conflito).

Sanity: 11 .py do projeto passam no ast.parse, panorama360 exporta todos os
símbolos importados, nenhum caller externo das funções removidas.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 03:57:15 -03:00
.claude Add panorama360 view, big calibrate_interactive rework, .claude config 2026-05-23 23:24:25 -03:00
legacy initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
weights add lane_model weights (best.pt + last.pt) + Colab notebook updates 2026-05-24 02:19:57 -03:00
.gitignore add lane_model weights (best.pt + last.pt) + Colab notebook updates 2026-05-24 02:19:57 -03:00
active_learning.py add lane training pipeline: dataset builder + YOLO11n-seg + active learning 2026-05-23 22:58:44 -03:00
avm2_render.py Add panorama360 view, big calibrate_interactive rework, .claude config 2026-05-23 23:24:25 -03:00
avm_render.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
build_dataset.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
build_lane_dataset.py add lane training pipeline: dataset builder + YOLO11n-seg + active learning 2026-05-23 22:58:44 -03:00
calibrate_interactive.py Merge: une local (panorama360 + calibrate_interactive rework + .claude) com remote (lane pipeline + ByteTrack + AVM2 TPS + lane_model) 2026-05-24 03:57:15 -03:00
calibrate_visual.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
camera_classifier.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
CLAUDE.md initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
custom_loss.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
extract_cam_frames.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
fisheye.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
fsd_render.py fix AVM2 perf regression + drivable mask overlay nos 4 thumbnails 2026-05-23 22:58:26 -03:00
lane_classical.py add lane training pipeline: dataset builder + YOLO11n-seg + active learning 2026-05-23 22:58:44 -03:00
lane_model_infer.py add lane training pipeline: dataset builder + YOLO11n-seg + active learning 2026-05-23 22:58:44 -03:00
lane_pipeline.py fix AVM2 perf regression + drivable mask overlay nos 4 thumbnails 2026-05-23 22:58:26 -03:00
license_plate.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
main.py perf: skip lane_model em AVM modes + fix dessync visual das side cams 2026-05-24 03:08:11 -03:00
make_quadrants_label.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
openpilot_render.py fix AVM2 perf regression + drivable mask overlay nos 4 thumbnails 2026-05-23 22:58:26 -03:00
panorama360.py Add panorama360 view, big calibrate_interactive rework, .claude config 2026-05-23 23:24:25 -03:00
person_detector.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
README.md add ByteTrack vehicle tracking + lane curvature/offset HUD in openpilot 2026-05-23 16:17:25 -03:00
tesla_render.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
train_camera_classifier.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00
train_colab.ipynb add lane_model weights (best.pt + last.pt) + Colab notebook updates 2026-05-24 02:19:57 -03:00
train_lane_model.py add lane training pipeline: dataset builder + YOLO11n-seg + active learning 2026-05-23 22:58:44 -03:00
vehicle_tracker.py add ByteTrack vehicle tracking + lane curvature/offset HUD in openpilot 2026-05-23 16:17:25 -03:00
yolopv2_lib.py initial commit: BYD 360 cameras processing pipeline 2026-05-23 06:31:28 -03:00

BYD 360 — cameras processing

Pipeline de processamento de vídeo dashcam BYD 360° (4 câmeras fisheye stitched) com YOLO. Detecta veículos, pessoas e placas em cada câmera, classifica dinamicamente qual câmera é cada quadrante (frente/trás/esq/dir), e renderiza em quatro estilos: openpilot first-person, AVM (Around View Monitor) surround top-down, Tesla FSD top-down via IPM, e legacy fsd.

Layout do vídeo de entrada

Vídeos 2x2 stitched (ex: 1920x1080 ou 2560x1920) com 4 cams fisheye:

+-------+-------+
|  TL   |  TR   |   TL = câmera esquerda,  TR = câmera traseira
+-------+-------+
|  BL   |  BR   |   BL = câmera frontal,   BR = câmera direita
+-------+-------+

(Confirmado para o dashcam BYD 360 usado neste projeto. Outros dashcams podem ter layout diferente — o camera_classifier detecta automaticamente.)

Estrutura

.
├── main.py                     # entrypoint CLI (offline / realtime, 5 estilos)
├── yolopv2_lib.py              # YOLOPv2 inference batched + CUDA Graphs
├── person_detector.py          # YOLOv8 wrapper (classe 0 COCO)
├── license_plate.py            # YOLOv8 placas + EasyOCR opcional
├── camera_classifier.py        # CameraClassifier YOLO26-cls (detecta layout)
├── fisheye.py                  # CROPS por quadrante (tira HUD/bumper/vignette)
│
├── avm_render.py               # AVM v1 legado (warps empíricos)
├── avm2_render.py              # AVM v2: stitch via calibration.json (8 pts)
├── tesla_render.py             # Tesla-style top-down via IPM (homografia)
├── fsd_render.py               # FSD legado (cars como icons)
├── openpilot_render.py         # comma.ai openpilot first-person
│
├── lane_pipeline.py            # poly fit + curvatura + offset (adapt Camera-based-ADAS)
├── vehicle_tracker.py          # ByteTrack wrapper (IDs persistentes)
├── build_dataset.py            # extrai dataset 4-classes dos vídeos
├── custom_loss.py              # BonusPenaltyClassificationLoss
├── train_camera_classifier.py  # treino com loss customizado
├── extract_cam_frames.py       # extrai 1 frame por cam pra calibração
├── calibrate_interactive.py    # GUI: arrasta 8 pontos pra calibrar AVM
├── calibrate_visual.py         # render lado-a-lado de calibração IPM
├── make_quadrants_label.py     # gera _quadrants_labeled.jpg pra confirmar layout
│
├── weights/                    # pesos modelo (camera_classifier_v2.pt versionado;
│                               # YOLOPv2/YOLOv8/license_plate ignorados — baixar separado)
├── assets/                     # ego_car.png (silhueta top-down opcional)
├── legacy/                     # _yolopv2_demo.py, _yolopv2_utils.py
├── graphify-out/               # mapa do projeto (graph.html, GRAPH_REPORT.md)
│
├── calibration.json            # 8 pontos AVM por cam (gitignored, específico do veículo)
└── CLAUDE.md                   # contexto p assistentes de IA

Setup

Requer Python 3.11, GPU NVIDIA com driver compatível (testado em GTX 750 Ti com CUDA 12.1) — ou CPU only.

python3.11 -m venv venv
source venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install --index-url https://download.pytorch.org/whl/cu121 torch==2.5.1 torchvision==0.20.1
pip install ultralytics opencv-contrib-python numpy supervision
# (opencv-contrib-python no lugar de opencv-python pq usamos
# cv2.createThinPlateSplineShapeTransformer no AVM2; supervision pra ByteTrack)
# Opcional p OCR de placas:
pip install easyocr

Pesos pré-treinados (baixar uma vez):

mkdir -p weights
# YOLOPv2 (vehicles + drivable area + lane lines, multi-task):
wget https://github.com/CAIC-AD/YOLOPv2/releases/download/V0.0.1/yolopv2.pt -O weights/yolopv2.pt
# YOLOv8n (person detector via ultralytics):
python -c "from ultralytics import YOLO; YOLO('yolov8n.pt')" && mv yolov8n.pt weights/
# YOLOv8 license plate (opcional):
# https://huggingface.co/keremberke/yolov8n-license-plate → weights/license_plate.pt

O classificador de câmeras (weights/camera_classifier_v2.pt, ~3MB) está versionado — pronto pra uso.

Como rodar

Visualização ao vivo

source venv/bin/activate

# openpilot first-person (front cam só) — modo padrão, leve
python main.py --device cuda --realtime --video videos/X.mp4

# AVM v2 surround top-down (4 cams stitched usando calibration.json)
python main.py --device cuda --realtime --style avm2 --video videos/X.mp4

# Tesla-style top-down via IPM (faixas projetadas em metros)
python main.py --device cuda --realtime --style tesla --video videos/X.mp4

# AVM legado
python main.py --device cuda --realtime --style avm --video videos/X.mp4

Gerar mp4

python main.py --style openpilot --save runs/demo.mp4 --max-frames 1000 --no-display

Desabilitar plate detector (libera VRAM em GPUs pequenas)

python main.py --device cuda --realtime --plate-weights /tmp/nonexistent.pt

Calibração AVM (8 pontos / 4 cams)

Pra rodar --style avm2 corretamente, gera um calibration.json específico do seu veículo:

# 1. Extrai um frame de cada câmera (lente completa, sem fisheye crop)
python extract_cam_frames.py --video Videos_training/X.mp4 --frame 500 --no-crop

# 2. Abre GUI interativa pra arrastar 8 pontos (2 por cam: TL + BR diagonal)
python calibrate_interactive.py
# Mouse: arrasta os pontos verdes (TL) e vermelhos (BR)
# 1/2/3/4 = selecionar cam ativa (vai pra frente)
# E = rotacionar imagem da cam ativa 90° CW
# T = toggle imagens (só borda)
# S = salvar calibration.json
# Q = sair

calibration.json é gitignored — cada veículo tem o seu.

Treino do classificador de câmeras

# 1. Coloca vídeos extras em Videos_training/
# 2. Extrai dataset rotulado (TL=esq, TR=tras, BL=frente, BR=dir)
python build_dataset.py
# Saída: dataset/{train,val}/{esq,tras,frente,dir}/*.jpg

# 3. Treina YOLO26n-cls com loss customizado (bonus por acerto + penalty por erro)
python train_camera_classifier.py --epochs 20 --device cuda --batch 32

# Resultado: runs/cls/byd-cameras/weights/best.pt
# Copiar para weights/camera_classifier.pt pra usar no main.py

Decisões importantes (rationale)

  • YOLOPv2 vs YOLOv8 para veículos: YOLOPv2 entrega vehicles + drivable area + lane lines numa pass só, então é o vehicle_model no main. YOLOv8 entra só para pessoas e placas.
  • Crop fisheye antes da inferência: YOLOPv2 foi treinado em BDD100K (rectilinear). Sem crop, fisheye distorce demais e gera detecções fantasmas. Coeficientes em fisheye.py:CROPS tunados empiricamente.
  • AVM2 usa lente CHEIA: pra stitching visual o quadrante uncropped (lente fisheye redonda completa) entra como cam_raw no results dict. A máscara elíptica no renderer só pinta o conteúdo da lente, sem mostrar os cantos pretos.
  • CUDA Graphs no YOLOPv2: capturadas por batch-size (1 e 3). Reduz overhead PyTorch eager. Fallback eager se a captura falhar.
  • Loss customizado para classificador de câmeras: L = CE × penalty_when_wrong - bonus_amt × conf_correct × correct_mask. Injetado via callback on_train_start.
  • Ordem de carregamento dos modelos: YOLOPv2/Person/Plate ANTES do classifier por causa de um bug do ultralytics 8.4.x + torch 2.5.1 que zera torch.cuda.device_count() em model.predict(device='cpu').
  • Lane curvature/offset via lane_pipeline: o openpilot_render computa raio de curvatura (m) + offset do centro (m) usando a lane_line mask do YOLOPv2 warpada pro BEV (IPM 4 pts). Faz sliding window + poly fit 2ª ordem (técnica clássica do Camera-based-ADAS de ahmad12hamdan99) e exibe no HUD inferior.
  • ByteTrack para IDs persistentes: cada veículo detectado pela YOLOPv2 (front cam) recebe um tracker_id estável entre frames via supervision's ByteTrack. IDs aparecem como #N ao lado de cada bbox no openpilot render. Mantém ID mesmo em oclusões curtas (até 30 frames perdidos).

Hardware testado

  • Local GPU: GTX 750 Ti (2GB VRAM, compute 5.0) — funciona com torch 2.5.1+cu121. Limite VRAM: openpilot OK, AVM bem lento, plate detector causa OOM.
  • Local CPU: AMD Ryzen 5 5500 — ~1.8 fps openpilot (sem plate), 0.22 fps com plate.
  • Remoto: Ryzen 5 5600 (10 cores) + AMD RX 5700 (Vulkan via llama.cpp, ROCm experimental). Disponível para training CPU.

Estilos de renderização (--style)

Estilo Cams Saída Uso
openpilot front first-person com path ribbon + HUD default, leve
avm 4 surround com warps empíricos legado legacy
avm2 4 surround via calibration.json (8 pts) recomendado p 360°
tesla 4 top-down via IPM (homografia) experimental
fsd front + sides top-down legado com icons legacy

graphify

O mapa de conhecimento do projeto está em graphify-out/ (gitignored). Para gerar/atualizar:

# Pipeline completo (primeira vez)
/graphify

# Incremental (depois de mudanças)
/graphify --update

Outputs:

  • graphify-out/graph.html — mapa interativo navegável
  • graphify-out/GRAPH_REPORT.md — god nodes, surprising connections, communities

Licença

YOLOPv2 modelo: MIT (CAIC-AD). Outros componentes: ver headers individuais.