cd /news/computer-vision/netryx-find-where-a-street-photo-was… · home › topics › computer-vision › article
[ARTICLE · art-155902] src=github.com ↗ pub= topic=computer-vision verified=true sentiment=↑ positive

Netryx – Find where a street photo was taken, to the block, offline

Netryx released Astra V2, an open-source geolocation system that matches a single street photo against a database of street-view panoramas to return GPS coordinates accurate to within a few meters, running offline. The V2 pipeline replaces the original nine-stage design with three stages: MegaLoc (CVPR 2025, a DINOv2 ViT-B/14 model producing 8448-dim descriptors PCA-reduced to 1024) retrieves the top 500 candidate locations, MASt3R (ECCV 2024) performs dense 3D matching to confirm the exact spot, and spatial consensus picks the most trustworthy cluster of matches. Netryx says the rebuild drops the earlier CosPlace, DISK, LightGlue, LoFTR and RANSAC stack, improves matching on partial or heavily cropped images, and adds index sharing through a Community Hub on Hugging Face plus offline .netryx bundles.

read13 min views5 publishedOct 23, 2026
Netryx – Find where a street photo was taken, to the block, offline
Image: Michielbdejong (auto-discovered)

State-of-the-art AI geolocation from a single image.

The Idea • How It Works • Getting Started • Community Hub • Installation

You have a photograph. Maybe it's a screenshot from a video. Maybe it's a cropped, blurry phone photo someone posted online. Maybe it shows just a storefront, a stretch of road, or the corner of a building. You want to know exactly where it was taken.

Netryx Astra V2 answers that question.

It's an open-source geolocation system that takes a single image and finds the precise GPS coordinates by matching it against a database of street-view panoramas. Upload your photo, and within minutes it tells you the street, the city, the coordinates — down to a few meters.

What makes V2 different from the original Netryx (and from other tools out there) is the matching pipeline. We rebuilt everything from the ground up using two models that didn't exist when we started this project:

MegaLoc (CVPR 2025) — the most accurate image retrieval model for place recognition, trained across six datasets covering indoor, outdoor, day, night, and seasonal variations. It finds the right neighborhood. #

MASt3R (ECCV 2024) — a 3D-aware dense matcher that understands the geometry of scenes, not just pixel patterns. It confirms the exact location, even from partial or heavily cropped photos that would break traditional matchers.

The result is a three-step pipeline that's both simpler and more accurate than the nine-stage system it replaced.

The original Netryx used CosPlace for retrieval and a stack of DISK + LightGlue + LoFTR + RANSAC + descriptor hopping + neighborhood expansion for verification. It worked, but it was fragile — lots of heuristics layered on top of each other, each one a workaround for a limitation in the previous stage.

V2 threw all of that away. Here's what replaced what:

V1 (Original) V2 (Astra)
Finding candidates CosPlace (ResNet-50, 512-dim) MegaLoc (DINOv2 ViT-B/14, 8448-dim → PCA 1024)
Confirming matches DISK + LightGlue + RANSAC MASt3R dense 3D matching
Handling edge cases LoFTR fallback, descriptor hopping, neighborhood expansion, Ultra Mode Spatial consensus — that's it
Total pipeline stages 9+ 3
Partial image matching Weak — sparse keypoints fail on small overlaps Strong — MASt3R finds dense correspondences in tiny regions
Sharing indexes Not possible Community Hub via Hugging Face + offline .netryx bundles

The simplification isn't just aesthetic. Fewer stages means fewer places for things to go wrong, faster searches, and code that's actually maintainable.

The pipeline has three stages. That's not an oversimplification — it's genuinely just three stages.

Query Image
     │
     ▼
┌─────────────┐
│   MegaLoc   │  "Where in the city could this be?"
│  Retrieval  │  
└─────┬───────┘
      │  Top 500 candidates
      ▼
┌─────────────┐
│   MASt3R    │  "Is this actually the same place?"
│   Matching  │  
└─────┬───────┘
      │  Scored candidates
      ▼
┌─────────────┐
│   Spatial   │  "Which cluster of matches is most trustworthy?"
│  Consensus  │  
└─────┬───────┘
      │
      ▼
  📍 GPS Coordinates

Your query image gets converted into a compact descriptor — a 8448-dimensional vector that captures the visual essence of the scene. This gets PCA-reduced to 1024 dimensions, then compared against every indexed location via dot-product similarity.

We also extract a descriptor for a slightly zoomed-in center crop and for a horizontally flipped version of the query, then merge the results. This handles cases where the query is at a different zoom level or facing the opposite direction from the indexed view.

The output is the top 500 candidate locations from the index, ranked by visual similarity.

MegaLoc is from Gabriele Berton's lab (the same group that made CosPlace and EigenPlaces). It's the latest in their line of work, trained on SF-XL, GSV-Cities, MSLS, and landmark retrieval data simultaneously. No other retrieval model consistently beats it across every benchmark — indoor, outdoor, urban, rural, day, night.

For each of those 500 candidates, we download the corresponding street-view panorama, crop it at the indexed heading angle, and run MASt3R to find dense pixel correspondences between the query and the crop.

This is where the magic happens for difficult queries. Traditional matchers like SuperPoint + LightGlue extract maybe 500-2000 sparse keypoints and try to match them. If your query image only overlaps 20% with the database image, there might only be 50 co-visible keypoints — not enough for a reliable match.

MASt3R works completely differently. It treats matching as a 3D reconstruction problem, predicting dense point maps and local feature descriptors for every pixel. Even a small overlapping region produces hundreds of reliable correspondences, because it understands the 3D structure of the scene, not just 2D pixel patterns.

On the Map-free localization benchmark (single reference image, viewpoint changes up to 180°), MASt3R beats previous methods by 30%. That's not an incremental improvement — it's a generational leap.

Here's the problem with just picking the candidate with the highest match score: false positives exist. Two identical chain restaurants 5km apart will both produce high MASt3R scores. A row of Soviet-era apartment blocks all look the same.

Spatial consensus solves this. We divide the search area into ~50-meter grid cells and cluster all the good matches geographically. Each cell gets a score based on the combined evidence from all matches in that cell and its neighbors.

A single outlier with 200 inliers at the wrong location gets outscored by a cluster of 5 matches with 80-150 inliers each at the right location. The winning cluster's best match becomes the final answer.

This is why accuracy holds up even at larger search radii where there are more look-alike locations.

We can observe in this picture, there is absolutely nothing to go on, it is just a small cropped part. Conventional OSINT would absolutely fail here. Yet Netryx Astra geolocated it down to its exact coordinates with no metadta whatsoever or clues beforehand running compltely locally.

A small cropped picture of a building, that's all it took to find it's location in a 1km radius in Moscow.

This is the part we're most excited about.

Indexing a city takes hours of compute time. It's wasteful for every user to independently index the same city. So we built a sharing system: one person indexes Moscow, uploads the result, and everyone else downloads it in minutes.

The fastest way. Someone else already did the indexing work — you just download their pre-built index.

Set mode to Search, click Run Search, and select your query image. The map coordinates and search radius auto-populate from the index metadata. This feature only works if the community contributes and supports each other, if you index a region, we will all be greatful if you upload it.

IMPORTANT NOTE: if application freezes due to running out of application memory while fitting PCA, use this command in terminal! python3 -c "from test_super import build_compact_index; build_compact_index()"

Want to index a city or area that nobody's done yet? The app handles everything — down panoramas, extracting descriptors, building the search index.

python test_super.py
  1. Set mode to Create
  2. Enter the center coordinates (latitude, longitude) and radius in km
  3. Click Create Index
  4. Wait. For 1km radius, expect ~20-30 minutes. For 5km, a few hours. For 10km, overnight.

What's happening under the hood: the app generates a grid of points within the radius, finds all available panorama locations, downloads each panorama as tiles and stitches them, crops each panorama at multiple heading angles, extracts MegaLoc descriptors for each crop, fits PCA on all descriptors, and builds a compact search index.

Got a .netryx file from a friend, a Discord server, or a download link? Just click 📥 Import Index in the app, select the file, and you're ready to search. No account needed, no internet needed — it's a fully offline workflow.

Indexes are hosted on Hugging Face Hub as public datasets. Anyone can download without an account. Contributing (up) requires a free Hugging Face account.

From the GUI: Click the 🌐 Community Hub button to browse, search, and download available indexes. Click ⬆ Upload Current Index to share yours.

Index bundles use the .netryx format — a ZIP archive containing:

  • PCA-reduced MegaLoc descriptors (the actual search vectors)
  • Coordinate metadata (lat/lon/heading/panoid for every entry)
  • The fitted PCA model (needed to transform query descriptors at search time)
  • A manifest with coverage info (center, radius, entry count, creator, etc.)

When you export, geographic filtering happens automatically. If your index contains Moscow + Paris + Tokyo but you export "Moscow 1km", only the Moscow entries get included. You can slice specific regions from a larger index without any manual work.

Don't want to use Hugging Face? Just export and share the file however you want:

python netryx_hub.py export \
  --index-dir ./netryx_data/index \
  -o moscow_1km.netryx \
  --city moscow --radius 1 --lat 55.75 --lon 37.62


python netryx_hub.py import moscow_1km.netryx -o ./netryx_data/index

Mac / Linux:

git clone https://github.com/sparkyniner/Netryx-Astra-V2-Geolocation-Tool.git
cd Netryx-Astra-V2-Geolocation-Tool
./setup.sh

Then start Netryx with ./run.sh, or on a Mac just double-click Netryx.command in the folder.

Windows: install Python 3.12 and Git first, then:

git clone https://github.com/sparkyniner/Netryx-Astra-V2-Geolocation-Tool.git
cd Netryx-Astra-V2-Geolocation-Tool

Double-click setup.bat to install everything. When it finishes, double-click run.bat to start Netryx.

That's it. Setup finds a suitable Python on your computer (3.10–3.12, even if your default is newer), creates a virtual environment, installs the dependencies, downloads MASt3R next to the repo and pre-downloads the model weights. It's safe to run again: finished steps are skipped. If anything is missing, it tells you exactly what to install.

When Netryx opens, press Try the demo at the top of the sidebar. It downloads a small sample index of central Moscow (about 180 MB, once) and loads a sample photo taken there. Press Run Search and watch it find the spot. The guided tour (Help & tour) explains every part of the window.

  • Python 3.10, 3.11 or 3.12 with Tk (the python.org installers include it)
  • macOS (Apple Silicon via MPS),
  • Linux (NVIDIA GPU via CUDA, AMD GPU via ROCM), or
  • Windows (NVIDIA GPU via CUDA)
  • 8GB+ RAM for searching (16GB+ recommended for indexing large areas)
  • ~2GB disk per city index

MASt3R weights download automatically from Hugging Face on first run.

Your folder structure should look like this:

some_folder/
├── Netryx-Astra-V2-Geolocation-Tool/   # This repo
│   ├── test_super.py
│   ├── megaloc_utils.py
│   ├── mast3r_utils.py
│   ├── netryx_hub.py
│   └── ...
└── mast3r/                # Cloned separately
    ├── mast3r/
    ├── dust3r/
    └── ...

mast3r_utils.py automatically finds and imports the adjacent mast3r/ directory at runtime. No path configuration needed.

Everything runs on Apple Silicon out of the box. The code handles MPS quirks automatically — CPU fallback for unimplemented ops, monkey-patching of .view() → .reshape() for non-contiguous tensors, and MPS cache cleanup during long indexing runs.

If you have an M1/M2/M3/M4 Mac, it'll use GPU acceleration automatically. No configuration needed.

You will need to install rocm/pytorch for your specific device manually to the venv after running the install script.

Use TheRock pytorch builds for your device: https://github.com/ROCm/TheRock/blob/main/RELEASES.md#installing-pytorch-python-packages

To install for example, for RX7xxx series cards:

pip install --index-url https://rocm.nightlies.amd.com/v2/gfx110X-all/ torch torchaudio torchvision

NOTE: ensure the user is part of the render group:

sudo usermod -aG render <userid>

and the base driver is installed: https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/quick-start.html#amd-gpu-driver-installation

Netryx-Astra-V2-Geolocation-Tool/
├── test_super.py          # Main application — GUI, pipeline, everything
├── megaloc_utils.py       # MegaLoc model , descriptor extraction, PCA
├── megaloc_model.py       # Self-contained MegaLoc architecture (fallback if torch.hub fails)
├── mast3r_utils.py        # MASt3R  and dense matching
├── netryx_hub.py          # Community Hub — upload, download, export, import
├── README.md
├── LICENSE
└── requirements.txt

netryx_data/
├── megaloc_parts/         # Raw 8448-dim descriptor chunks (created during indexing)
└── index/                 # The compact search index
    ├── megaloc_descriptors.npy   # PCA-reduced descriptors
    ├── metadata.npz              # Coordinates, headings, panoid IDs
    ├── megaloc_pca.pkl           # PCA model for query-time transformation
    └── manifest.json             # Present if downloaded from Community Hub

../mast3r/                 # https://github.com/naver/mast3r

You can tune these parameters in test_super.py if needed. The defaults work well for most use cases.

Parameter Default What it does
INDEX_TARGET_DIM 1024 PCA output dimension. 512 = smaller index, slightly less accurate. 1024 = good balance.
MAX_PANOID_WORKERS 16 How many panoramas to download in parallel during indexing
MAX_DOWNLOAD_WORKERS 100 Concurrent tile download connections (each pano = 8 tiles)
EARLY_EXIT_INLIER_THRESHOLD 450 If MASt3R finds this many dense matches, stop searching early — it's a confident hit
MAST3R_STAGE2_TOP_N 500 How many MegaLoc candidates to run through MASt3R

The main thing you might want to adjust is INDEX_TARGET_DIM — dropping to 512 halves your index size with only ~2-3% accuracy loss.

We believe in being upfront about what this tool can and can't do.

It only finds places that are in the index. If a location hasn't been indexed by you or downloaded from the community, it won't be found. No model, no matter how advanced, can match against data that doesn't exist. The accuracy ceiling is set by coverage, not by the models.

Repetitive architecture causes false positives. Chain stores, suburban housing developments, rows of identical apartment blocks — these genuinely look the same from street level. Spatial consensus helps (a cluster of nearby matches beats a single isolated outlier), but it's not bulletproof, especially at large search radii (10km+) where there are more look-alike candidates. This is an unsolved problem in the field, not a limitation specific to Netryx.

Coverage gaps exist in some areas. Rural areas, developing countries, newly built neighborhoods, and indoor spaces may have limited or no street-level imagery available for indexing.

This is not a real-time system. Running MASt3R on 500 candidates takes several minutes on a consumer GPU. This is designed for forensic analysis — investigative journalism, human rights documentation, OSINT research, insurance fraud investigation — not for navigation or live tracking.

Indexing requires meaningful compute. MegaLoc's DINOv2 backbone is ~5x heavier than the CosPlace backbone used in V1. Indexing a 1km radius takes ~20-30 minutes. A full city (10km+) is an overnight job. That's why the Community Hub exists — so this cost is paid once and shared. Also the match with most inliners isnt neccsarily the correct match that's why it returns multiple results which you can cross check yourself.

If you use Netryx Astra V2 in your research or work, we'd appreciate a citation:

@software{netryx_astra_v2,
  title={Netryx Astra V2: State-of-the-Art AI Geolocation},
  author={Sairaj Balaji},
  year={2026},
  url={https://github.com/sparkyniner/Netryx-Astra-V2-Geolocation-Tool}
}

MIT License. See LICENSE for details.

MegaLoc weights are MIT licensed. MASt3R is Apache 2.0 licensed. DINOv2 is Apache 2.0 licensed. Community-shared indexes are CC-BY-4.0.

Built by Sairaj Balaji

Also built PrismX featured in Fast Company · 404 Media · Deutsche Welle

── more in #computer-vision 4 stories · sorted by recency
── more on @netryx 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/netryx-find-where-a-…] indexed:0 read:13min 2026-10-23 · —