Geo-Referencing and Digitization of Scanned Maps

Introduction

This sample guide explains the steps for automatically geo-referencing and digitizing scanned maps. Some of the important terms used in this guide are as follows:

  • Scanned Map: Refers to the digital, scanned copy of a scientific paper map.
  • Geo-referencing: Refers to the process of assigning real-world coordinates to pixels of the scanned map.
  • Digitizing: Refers to the process of converting geo-referenced data to digital format(shapefile).

Valuable Geo-spatial information is contained in a wide variety of maps available in the form of images. Unfortunately, we can’t analyse this data without digitizing it. The conventional approach is to manually extract data and store it in a digital format. This guide details a method using computer vision techniques to automatically extract details from a set of scanned maps, find reliable feature points (control points), register the maps to different parts of the world, and ultimately overlay the valuable Geo-spatial data depicted in these maps onto the search region image (for instance, world map).

This guide illustrates the stepwise use of six APIs that are capable of geo-referencing and digitizing a scanned map image onto a search region image (for instance, world map).

Data Used

The data used in this guide are the scanned maps extracted from the series of handbooks called Mammals of the World, a series which contains the information of species across the world, including regions where the species are found. We extracted the images from the scanned book in order to Geo-reference and digitize the species on the search region image (for instance, world map).

Below are some sample scanned maps with depicted species' region:

(i) Bandicota bengalensis (Bandicoot Rat)
(ii) Saccostomus campestris (Southern African Pouched Mouse)
(iii) Tylomys watsoni (Watson’s Climbing Rat)

Implementation in arcgis.learn

Let's see how scanned maps are geo-referenced and digitized with arcgis.learn.

Imports

Import the ScannedMapDigitizer class from arcgis.learn module.

Input
from arcgis.learn import ScannedMapDigitizer

Object initialization

Below are the parameters to be passed into ScannedMapDigitizer:

  • input_folder: The path to the folder that contains scanned map images

  • output_folder: The path to the folder where intermediate results and output should get generated with image name

Note: Intermediate results are the outputs from the below-mentioned methods which are required for the following steps as input.

Input
smd = ScannedMapDigitizer("path_to_scanned_maps", "path_to_output_folder")

Create Masks

This method extracts binary mask images using the scanned maps corresponding to color inputs fed by the user.

  • The parameters to be passed are as follows:

    • color_list: A list containing different color inputs (r, g, b). For example, if an image contains two colors to represent two different specie, the list should contain RGB values for both the colors as tuples. syntax: [(r, g, b), (r1, g1, b1)

    • color_delta: A value that defines the range around the threshold value for a specific color used for creating the mask images. Default value is 60.
      Note: The minimum value of color_delta is 0, which means masking the image for the same color used in the color list. Increasing the value will expand the threshold/range of the color, which will be useful for extracting the nearest color shades. Please note that bigger values of color_delta can end up extracting the unwanted pixels as part of the mask.

    • kernel_size: A list of 2 integers corresponding to size of the morphological filter operation's closing and opening respectively. The default value is None. This indicates that no morphological operations are performed.
      Following illustration shows the usage/selection of the appropriate morphological operation

      By increasing/decreasing the value of kernel_size parameter we can remove the noise inside and outside the region thereby generating a better mask for the image. Please note that the use of kernel_size is only advised when there is a lot of noise present after masking the image using color thresholding.

    • kernel_type: A string value defining the type/shape of the kernel. kernel type can be "rect", "elliptical" or "cross". The default value is rect.

    • show_result: A Boolean value denoting whether to display results. Set to True to visualize results, set to False otherwise.

  • The function generates a folder with name "masks" that contains binary masks for all the colors and mask_color_details.h5 which contains region wise color codes.

For a given scanned map image, the method traverses the colors in the color_list and generates a color threshold range using color_delta for each color. The computed ranges help to generate binary masks for each color. The masks are then further processed to remove noise using the kernel_size and kernel_type parameters.

Input
smd.create_mask(color_list=[[100, 164, 8]], color_delta=70, kernel_size=[3, 3], kernel_type="rect", show_result=True)

Output

Create Template Image

This method extracts binary mask images corresponding to the land regions present in the scanned maps.

  • The parameters to be passed are as follows:

    • color: r, g, b value representing land color. The color parameter is required for extracting the land region and generating the binary mask. syntax: [r, g, b].

    • color_delta: A value that defines the range around the threshold value for a specific color used in creating the mask images. Default value is 10.

    • kernel_size: An integer denoting size of the morphological kernel. Used in removing the noise from the masked image. The morphological operation used is dilation. Default value is 2.

    • show_result: A Boolean value denoting whether to display results. Set to True to visualize results, set to False otherwise.

  • The function generates a folder with the name template_image with binary masks for the land region.

This method generates templates from scanned maps and color masks that are used in the subsequent step of template matching.

Input
smd.create_template_image([254, 254,254], 10, 4, show_result= True)

Output

Prepare Search Region

This method prepares the search region in which the prepared templates are to be searched. Specifically, it produces the binary mask corresponding to the land region in an image (bigger than the template image). This method accepts an image or a shapefile as input.

A setter function, *get_search_region_extent*, is used to set the extent of the search region.
The required values are as follows:

  • spatialReference: A spatial reference can be defined using a well-known ID (WKID)
  • xmin: Left longitude value
  • ymin: Bottom latitude value
  • xmax: Right longitude value
  • ymax: Top latitude value

The extent will be used to extract or crop a specific region from the entire search region.

Input
extent = {
     'spatialReference': {'wkid': 4326},
     'xmin': -180,
     'ymin': -89,
     'xmax': 180,
     'ymax': 85 
   }

smd.set_search_region_extent(extent)
     

Once the extent of the entire search region is defined, the method prepare_search_region can be called to generate the binary mask of the search region.

  • The parameters to be passed are as follows:

    • search_image: Path to the bigger image/shapefile.
    • color: r, g, b value representing water color. The color parameter is required for extracting the water region and
           generating the binary mask. syntax: [r, g, b].
    • extent: Extent defines the inner longitude/latitude values within the search region. Extent takes a dictionary with

            the following key and value pair as input:<br/><br/>
      
      • spatialReference: A spatial reference can be defined using a well-known ID (WKID)
      • xmin: Left longitude value
      • ymin: Bottom latitude value
      • xmax: Right longitude value
      • ymax: Top latitude value

        Example: extent = {
                     'spatialReference': {'wkid': 4326},
                      'xmin': -180,
                      'ymin': -89,
                      'xmax': 180,
                      'ymax': 85
                 }
        

        Note: The defined extent will be extracted from the entire search region.
        Please make sure this extent lies inside, or is equal to the extent, that is set using set_search_region_extent.

    • image_height: Height of the search region.

    • image_width: Width of the search region.

    • show_result: A Boolean value denoting whether to display results. Set to True to visualize results, set to False otherwise.

  • The function generates a folder with the name search_region with the binary mask of the larger image..

Input
search_extent = {
        'spatialReference': {'wkid': 4326},
         'xmin': -180,
         'ymin': -89,
         'xmax': 180,
         'ymax': 85
    }
Input
smd.prepare_search_region("search_image.jpg/shape_file.shp", [173, 217, 219], search_extent, 2068, 3744, show_result=True)

Output

Match Template Multiscale

This method finds the location of the best match of a smaller image (template) in a search region image (for instance, world map) assuming it exists in the larger image. Multiple scales of the bigger image are used for this task because template matching is not scale-invariant.

The final output is generated using the 4 pairs of points obtained from matching the entire binary scanned map template image with the binary search region image.

  • Following are the parameters to be passed:

    • min_scale: An integer representing the minimum scale at which template matching is performed

    • max_scale: An integer representing maximum scale at which template matching is performed

    • num_scales: An integer representing the number of scales at which template matching is performed.

    • show_result: A Boolean value denoting whether to display results. Set to True to visualize results, set to False otherwise.

  • The function generates a folder with name template_match containing binary search region and a file with name "reference_homography.h5" that contains x-y coordinates of the matched template on search region image.
Input
smd.match_template_multiscale(0.2, 2.0, 40, show_result=True)

Output

Geo-reference Image

This method estimates the control point pairs by traversing the contours of template image and finding the corresponding matches on the search region ROI image. The search region ROI image is obtained by padding the detected bounding box in the template matching step. The computed control points are then filtered, and the outliers are removed. Filtered control points and search region extent are finally used to locate the scanned map on the search region image (for instance, world map).

  • Following are the parameters to be passed:
    • padding_param: A tuple that contains x-padding and y-padding at $0^{th}$ and $1^{st}$ index respectively. These padding values are used to create search region ROI that is used for computing the transformation for geo-referencing the image.
    • show_result: A Boolean value denoting whether to display results. Set to True to visualize results, set to False otherwise.

  • The function generates a folder with the name georeference_image with warped scanned map images and an XML file that contains the geographical coordinates of the image. The geo-referenced images can be opened inside ArcGIS Pro.
Input
smd.georeference_image((150, 50), show_result=True)

Output

Digitize Image

This method is the final step in the pipeline that maps the species' regions on the search region image (for instance, world map) using the computed transformations. Also, it generates the shapefiles for the species' region that can be visualized using ArcGIS Pro and further edited. Additionally, it generates a combined shapefile for all the species' region corresponding to all the scanned map images.

  • The parameters used are as follows:
    • show_result: A Boolean value denoting whether to display results. Set to True to visualize results, set to False otherwise.

  • The function generates a folder with name digitize_image containing mapped specie's region and shapefiles.
Input
smd.digitize_image(show_result=True)

Output

Conclusion

This guide explains how scanned maps are automatically geo-referenced and digitized. For every step in the workflow, we define a function and talk about its usage. This sample can be a starting point for developers to perform similar registration tasks by tuning the parameters.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.