# neerajjv/findx-language-driven-suspect-search architecture

> Architecture diagram of the GitHub repository neerajjv/findx-language-driven-suspect-search, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/neerajjv/findx-language-driven-suspect-search
- Repository: https://github.com/neerajjv/findx-language-driven-suspect-search

## Overview

#### Purpose and Entry Point
FindX is a local Python desktop investigation tool for locating people in CCTV footage from natural-language descriptions. The PyQt6 application starts at `app.py`, which composes the desktop UI and invokes the video-indexing/search core. The checked-in input corpus is a large local video set under `CCTV/` (for example, `CCTV/cam0001.mp4`).

#### Application Shell and UI Coordination
`src/ui/main_window.py` is the primary UI composition boundary. It coordinates:
- source selection and scan controls from `src/ui/sidebar.py`;
- text-query submission through `src/ui/top_bar.py`;
- result selection, video review, and restoration actions.
The UI is native PyQt6, not a web application; it binds long-running local ML/video work to interactive investigation views.

#### Video Ingestion and Sampling
`src/core/processor.py` owns the OpenCV-facing video-processing stage. It accepts either a CCTV directory or individual upload, iterates video frames at a configured sampling rate, and supplies frames plus source/timestamp context to detection. `src/config.py` is the likely central boundary for sampling and model/storage constants. Raw MP4 files remain the source of truth; derived crops and metadata feed subsequent stages.

#### Person Detection and Crop Production
`src/core/detector.py` applies YOLOv8 through Ultralytics to sampled frames and retains person detections. This separates expensive pixel-level inference from later semantic retrieval. Bounding boxes are used to generate person crops, preserving the originating video and timestamp so a retrieved crop can lead back to evidence playback.

#### Cross-Modal Embedding
`src/core/encoder.py` uses OpenAI CLIP ViT-B/16 with PyTorch to embed detected person crops into image vectors and investigator descriptions into text vectors in the same feature space. The common embedding representation is the contract between indexing and natural-language search; it enables clothing, accessory, and person-description matching without a separate text metadata schema.

#### Vector Index and Retrieval
`src/core/indexer.py` persists and queries a FAISS similarity index over CLIP image embeddings. The intended flow is: processed crop vectors enter FAISS during scan; a query is text-encoded; FAISS returns nearest person occurrences ranked by semantic similarity. The README identifies `cctv_index.faiss` as the retrieval cache, although that artifact is not present in the supplied tree. Result records must retain enough local metadata to resolve a hit back to crop, video, timestamp, and detection region.

#### Evidence Review and Restoration
`src/ui/results_grid.py` presents ranked crop matches, and `src/ui/viewer.py` plays the originating local MP4 at the selected timestamp, with the person region highlighted. `src/ui/restoration_panel.py` invokes `src/core/restoration.py`, which uses GFPGAN for face enhancement/upscaling. Restoration is a downstream visual-review operation, not part of the search index pipeline.

#### Runtime and Infrastructure Boundaries
The system runs locally on Python 3.9+ with PyQt6, OpenCV, Pillow/NumPy, PyTorch/Torchvision, Ultralytics YOLOv8, OpenAI CLIP, FAISS, and GFPGAN. CUDA-capable PyTorch/NVIDIA hardware is an optional acceleration path for detection and embedding. Models are local or dynamically loaded according to the README; no server, database, cloud service, or network API is evidenced by the repository tree.

Main entry points: [`src/core/encoder.py`](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/encoder.py) (CLIP encoder), [`src/ui/main_window.py`](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/main_window.py) (Main window), [`src/core/indexer.py`](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/indexer.py) (FAISS indexer), [`src/core/processor.py`](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/processor.py) (Video processor)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_desktop["Desktop UI"]
  node_app["Application entry<br/>Python entry point<br/>[app.py]"]
  node_main_window["Main window<br/>PyQt6 coordinator<br/>[main_window.py]"]
  node_sidebar["Scan controls<br/>PyQt6 view<br/>[sidebar.py]"]
  node_top_bar["Query input<br/>PyQt6 view<br/>[top_bar.py]"]
end

subgraph group_indexing["Indexing Pipeline"]
  node_cctv[("CCTV videos<br/>local MP4 corpus")]
  node_config["Configuration<br/>settings<br/>[config.py]"]
  node_processor["Video processor<br/>OpenCV pipeline<br/>[processor.py]"]
  node_detector["Person detector<br/>YOLOv8 inference<br/>[detector.py]"]
  node_crops["Person crops<br/>derived evidence"]
  node_encoder["CLIP encoder<br/>cross-modal ML<br/>[encoder.py]"]
end

subgraph group_retrieval["Search &amp; Review"]
  node_indexer["FAISS indexer<br/>vector retrieval<br/>[indexer.py]"]
  node_faiss_index[("FAISS index cache<br/>local vector index")]
  node_results_grid["Ranked results<br/>PyQt6 view<br/>[results_grid.py]"]
  node_viewer["Evidence viewer<br/>PyQt6 video review<br/>[viewer.py]"]
  node_restoration_panel["Restoration controls<br/>PyQt6 view"]
  node_restoration["Face restoration<br/>GFPGAN processing<br/>[restoration.py]"]
end

node_accelerator{{"Optional CUDA<br/>hardware acceleration"}}

node_app -->|"starts"| node_main_window
node_main_window -->|"coordinates"| node_sidebar
node_main_window -->|"coordinates"| node_top_bar
node_sidebar -->|"starts scan"| node_processor
node_cctv -->|"video input"| node_processor
node_config -.->|"sampling settings"| node_processor
node_processor -->|"sampled frames"| node_detector
node_detector -->|"person crops + context"| node_crops
node_crops -->|"image embeddings"| node_encoder
node_encoder -->|"crop vectors"| node_indexer
node_indexer -->|"persists and queries"| node_faiss_index
node_top_bar -->|"text description"| node_encoder
node_encoder -->|"query vector"| node_indexer
node_indexer -->|"ranked occurrences"| node_results_grid
node_results_grid -->|"selected hit"| node_viewer
node_viewer -->|"opens source video"| node_cctv
node_main_window -->|"coordinates"| node_restoration_panel
node_restoration_panel -->|"enhancement request"| node_restoration
node_detector -.->|"optional compute"| node_accelerator
node_encoder -.->|"optional compute"| node_accelerator

click node_app "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/app.py"
click node_main_window "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/main_window.py"
click node_sidebar "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/sidebar.py"
click node_top_bar "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/top_bar.py"
click node_config "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/config.py"
click node_processor "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/processor.py"
click node_detector "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/detector.py"
click node_encoder "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/encoder.py"
click node_indexer "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/indexer.py"
click node_results_grid "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/results_grid.py"
click node_viewer "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/viewer.py"
click node_restoration_panel "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/restoration_panel.py"
click node_restoration "https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/restoration.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_main_window,node_sidebar,node_top_bar toneBlue
class node_cctv,node_config,node_processor,node_detector,node_crops,node_encoder toneAmber
class node_indexer,node_faiss_index,node_results_grid,node_viewer,node_restoration_panel,node_restoration toneMint
class node_accelerator toneNeutral
```

## Components

### Desktop UI

Native PyQt6 investigation workflow.

- [Application entry](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/app.py): Python entry point · Composes and starts the desktop application. · `app.py`
- [Main window](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/main_window.py): PyQt6 coordinator · Coordinates source scanning, queries, results, and review. · `src/ui/main_window.py`
- [Scan controls](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/sidebar.py): PyQt6 view · Selects CCTV sources and starts scans. · `src/ui/sidebar.py`
- [Query input](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/top_bar.py): PyQt6 view · Submits natural-language person descriptions. · `src/ui/top_bar.py`

### Indexing Pipeline

Local video-to-vector processing.

- **CCTV videos**: local MP4 corpus · Raw footage is the source of truth.
- [Configuration](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/config.py): settings · Defines sampling, model, and storage constants. · `src/config.py`
- [Video processor](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/processor.py): OpenCV pipeline · Samples frames and preserves source and timestamp context. · `src/core/processor.py`
- [Person detector](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/detector.py): YOLOv8 inference · Detects people and creates contextualized crops. · `src/core/detector.py`
- **Person crops**: derived evidence · Crops retain video, timestamp, and detection-region metadata.
- [CLIP encoder](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/encoder.py): cross-modal ML · Embeds person crops and text in one feature space. · `src/core/encoder.py`

### Search & Review

Semantic retrieval and evidence inspection.

- [FAISS indexer](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/indexer.py): vector retrieval · Persists image vectors and resolves nearest occurrences. · `src/core/indexer.py`
- **FAISS index cache**: local vector index · Persisted CLIP image embeddings and occurrence metadata.
- [Ranked results](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/results_grid.py): PyQt6 view · Shows semantic crop matches. · `src/ui/results_grid.py`
- [Evidence viewer](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/viewer.py): PyQt6 video review · Plays source footage at the hit timestamp and highlights the region. · `src/ui/viewer.py`
- [Restoration controls](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/ui/restoration_panel.py): PyQt6 view · Starts optional face enhancement for review. · `src/ui/restoration_panel.py`
- [Face restoration](https://github.com/neerajjv/findx-language-driven-suspect-search/blob/master/src/core/restoration.py): GFPGAN processing · Enhances or upscales faces after retrieval. · `src/core/restoration.py`

### Other components

- **Optional CUDA**: hardware acceleration · Accelerates detection and embedding when available.

## Connections

- Application entry → Main window: starts
- Main window → Scan controls: coordinates
- Main window → Query input: coordinates
- Scan controls → Video processor: starts scan
- CCTV videos → Video processor: video input
- Configuration → Video processor: sampling settings
- Video processor → Person detector: sampled frames
- Person detector → Person crops: person crops + context
- Person crops → CLIP encoder: image embeddings
- CLIP encoder → FAISS indexer: crop vectors
- FAISS indexer → FAISS index cache: persists and queries
- Query input → CLIP encoder: text description
- CLIP encoder → FAISS indexer: query vector
- FAISS indexer → Ranked results: ranked occurrences
- Ranked results → Evidence viewer: selected hit
- Evidence viewer → CCTV videos: opens source video
- Main window → Restoration controls: coordinates
- Restoration controls → Face restoration: enhancement request
- Person detector → Optional CUDA: optional compute
- CLIP encoder → Optional CUDA: optional compute
