This repository contains code for the algorithm described in "Printed Map Geolocation Using Line Segments and Textureless SIFT-like Feature Matching".
It implements an algorithm for the registration of printed maps in a Geographic Information System such as OpenStreetMap. The registration is scale and rotation invariant, and aims at being a scalable first step in an Augmented Maps pipeline, preceding real-time tracking of perspective views of a map.
Here's what's needed to get started:
- Python 2
- NumPy (tested with version 1.8.2)
- SciPy (tested with version 0.14.1)
- OpenCV (tested with version 3.0.0-dev, but uses only basic functionality available in OpenCV 2), compiled with Python bindings
The code is organized in the following way:
datamanager.py
: code to make loading and saving data a breeze. It is used for example bymaps.rmsmap.RMSMap
, a class which does a fair bit of computations, to save and restore its state.geom/
: module containing geometry-related utilities__init__.py
: contains thegeom.Segments
class, a container for line segments used throughout the codeplanar.py
: utilities for planar geometrytransform.py
: utilities for computing general transformations
maps/
: code dealing with mapsbenchmarking.py
: contains a MapFuzzer class, which has a pleasant interface for adding different forms of noise to aDiscreteMap
density.py
: utilities to estimate segment densities and corresponding region sizesdiscretemap.py
: containsDiscreteMap
, the basic raster map container (multi-set image of segments)gcs/
: Geographic Coordinate System, contains modules used bymaps.mapprocessor
to load OpenStreetMap datagcs.py
: common interface for the various GCS__init__.py
: utility to find the adequate GCS parsing modulelatlong.py
: GCS class to parse latitude-longitude segment dataosgb36.py
: GCS class to parse segment data in OSGB36 coordinates
keypoint.py
: basicKeypoint
class for storing position, scale and orientation of keypointslabeller.py
: containsMultiSetLabeller
, a class for the creation and use of multi-sets, as used byDiscreteMap
lrpd.py
: classLRPD
to compute local road pattern descriptorsmapimager.py
: once OpenStreetMap data is pre-processed (normalized), this class makes creating arbitrary size raster images of the data easymapprocessor.py
: class to pre-process OpenStreetMap data, by parsing raw segment data and normalizing itmetricmap.py
: superclass ofDiscreteMap
, which stores metric information. Useful when the metric is known, or when groundtruth scale for a raster map is knownrmsmap.py
: classRMSMap
(Rotational Multi-Scale Map) to represent a raster map (DiscreteMap
) at multiple scales and describe itrmsmatcher.py
: classRMSMatcher
to match testRMSMap
s against an index of referenceRMSMap
s
results
: module to keep track of experiment results. When trying out different values for parameters, or running benchmarks, this module provides an interface to save and load (parameters, result) pairs (using the DataManager). New data can be transparently appended, and stored data can be retrieved and filtered (on both parameters and results).tool-map-distances.py
: standalone script to interactively display distances on an OpenStreetMap map in pixels or meterstool-road-selector.py
: standalone script to select roads in a map image using the mouse, and outputting a set of segments suitable for use in the registration.util/
: various utility functionsdata.py
: utilities to (mostly) load and savegeom.Segments
grid.py
:Grid
class to create and iterate over 2D gridsimage.py
: utilities pertaining to images and the drawing of segmentsprogressmeter.py
: helper class to display a customizable progress bar on the console