NAV
Python cURL

Introduction

The API is based on simple REST, so it can be queried by anything that supports HTTP, such as Python and cURL.

For Python, in1 provides a special library that wrap the REST calls for ease of use. Raw HTTP calls can also be performed by cURL or any programming language's native HTTP client. The right sidebar shows concrete examples for both, while the body of the page describes valid HTTP requests to the endpoints.

Check out the interactive Notebook!

Install client

# Using conda
conda create -n in1 python=3.7
conda install -c in1 in1
# Using docker
docker pull in1ai/client
sudo apt install curl

We recommend installing in1 from conda. Alternatively, in1 can also be installed as a docker image or from PyPI.

Install using Conda

The Conda package is the most flexible. It allows using in1 as a terminal command and integrating it into scripts. It does require create a conda environment with Python 3.6 or 3.7.

  1. Create a Python 3.6 or 3.7 environment: conda create -n in1 python=3.7
  2. Install from the in1 channel: conda install -c in1 in1

Install using Docker

The Docker image is guaranteed to work. It allows calling the terminal as described below, but is difficult to integrate into scripts.

  1. Pull and run docker image: docker pull in1ai/client

Install using PyPI

The in1 client is also available from PyPI. Some users experience difficulties installing all dependencies, specifically GDAL, however. This method's main advantage is that it is compatible with all Python versions and can be used both from the terminal and within scripts.

  1. Install using pip: pip install in1

When encountering GDAL issues, follow the below instructions. Alternatively, consider using Conda or Docker.

Terminal command

Replace <IN1_API_KEY> with your personal API key

in1 upsample --help
in1 upsample --api <IN1_API_KEY> -s bgri_in.tif -r bgri_4x_out.tif
docker run --rm -v $(pwd):/workspace in1ai/client \
    in1 upsample --help
docker run --rm -v $(pwd):/workspace in1ai/client \
    in1 upsample --api <IN1_API_KEY> \
    -s bgri_in.tif -r bgri_4x_out.tif
in1 upsample --help
in1 upsample -s bgri_in.tif -r bgri_4x_out.tif --api <IN1_API_KEY>
docker run --rm -v $(pwd):/workspace in1ai/client in1 upsample --help
docker run --rm -v $(pwd):/workspace in1ai/client \
    in1 upsample --api <IN1_API_KEY> \
    -s bgri_in.tif -r bgri_4x_out.tif

The Python client library will also install an in1 executable to allow super-resolving directly from the command line.

The terminal command is also available via the docker image. The normal command must then be prefixed with docker run --rm -v $(pwd):/workspace in1ai/client.

Demonstration by Jupyter Notebook

Also check out our interactive Notebook! It is the quickest way to see in1 in action.

Instant super resolution demo

Replace <IN1_API_KEY> with your personal API key

import os
import in1
import shutil
import numpy as np
import geopandas as gpd

# Download demo dataset and load random image using its index
print("Downloading dataset...")
index = in1.download_s2_dataset()

index = gpd.read_file(index)
source = os.path.join("./in1-s2-dataset", index.path.sample(1).iloc[0])
shutil.copyfile(source, "source-example.tif")

# Apply super resolution
print("Super-resolving source-example.tif (original: {})...".format(source))
result, profile, _ = in1.sisr(source, api_key="<IN1_API_KEY>", calc_metrics=False)

print("Writing image to file...")
in1.write(result, "result-example.tif", profile)
print("Done! See result-example.tif")
# Download
echo "Downloading demo dataset..."
curl https://in1-pub.s3.eu-central-1.amazonaws.com/in1-s2-dataset.tar.gz \
     -o in1-s2-dataset.tar.gz

# Extract archive and take arbitrary image
echo "Extracting demo dataset..."
tar xzf in1-s2-dataset.tar.gz
export IN1_SUBMISSION=`ls -d -1 in1-s2-dataset/*/*/*.tif | shuf -n 1`
cp $IN1_SUBMISSION source-example.tif

# Super-resolve!
echo "Super-resolving source-example.tif (original: $IN1_SUBMISSION)..."
curl -H "in1-api-key: <IN1_API_KEY>" \
     -F submission=@$IN1_SUBMISSION  \
     -o result-example.tif           \
     https://api.in1.ai/v1/sentinel-2
echo "Done! See result-example.tif"

To get started quickly, the example on the right allows for instant super resolution. It can be directly copy-pasted, only replacing the API key field, to see in1 in action.

Executing the scripts on the right will save a super-resolved image named result-example.tif to the current working directory. To do so, the example downloads an example dataset, sends a single image to the server and saves the result.

You can also see this code in action in our interactive Notebook.

Terminal command example

The instant super resolution python script can also be called directly from the terminal. Observe the magic with a single command:

in1 upsample --source path/to/source.tif --result path/to/result.tif --api <IN1_API_KEY>

Authentication

All calls require an API key, which should have provided to you. If not, please contact us. Furthermore, sufficient credits need to be associated with the account.

Create BGRI input raster

It is important to use the raw Sentinel-2 bands ESA provides as part of its products. These need to be the blue (band 2), the green (band 3), red (band 4) and infrared (band 8) bands at 10 meters, in that order. This can for example be done with the GDAL suite. See to the right for examples.

Replace the Sentinel-2 product and band file names with your own. We use S2A_MSIL2A_20210528T105621_N0300_R094_T31UET_20210528T141548.SAFE.zip product archive as an example.

unzip S2A_MSIL2A_20210528T105621_N0300_R094_T31UET_20210528T141548.SAFE.zip

cd S2A_MSIL2A_20210528T105621_N0300_R094_T31UET_20210528T141548.SAFE/
cd GRANULE/L2A_T31UET_A030979_20210528T110445/IMG_DATA/R10m/

gdalbuildvrt -separate bgri.vrt \
    T31UET_20210528T105621_B02_10m.tif \
    T31UET_20210528T105621_B03_10m.tif \
    T31UET_20210528T105621_B04_10m.tif \
    T31UET_20210528T105621_B08_10m.tif

gdal_translate bgri.vrt bgri.tif
unzip S2A_MSIL2A_20210528T105621_N0300_R094_T31UET_20210528T141548.SAFE.zip product archive

cd S2A_MSIL2A_20210528T105621_N0300_R094_T31UET_20210528T141548.SAFE/
cd GRANULE/L2A_T31UET_A030979_20210528T110445/IMG_DATA/R10m/

gdalbuildvrt -separate bgri.vrt \
    T31UET_20210528T105621_B02_10m.tif \
    T31UET_20210528T105621_B03_10m.tif \
    T31UET_20210528T105621_B04_10m.tif \
    T31UET_20210528T105621_B08_10m.tif

gdal_translate bgri.vrt bgri.tif
  1. Download the .SAFE.zip product and extract. Then navigate to the IMG_DATA/R10m directory. In this example we have the T31UET_20210528T105621 product.
  2. Build a virtual raster that stacks the BGRI bands with gdalbuildvrt.
  3. Convert virtual raster to a real raster with gdal_translate.

Use our demo dataset described below for pre-processed data to directly experiment with.

All processing requirements are:

Sentinel-2

Super-resolve your image

Call definition

def in1.sisr(
    raster: str,
    api_key: str,
    calc_metrics: bool = True,
) -> Tuple[
    np.ndarray,
    rasterio.profile.Profile,
    Optional[Dict[str, np.ndarray]]
]
curl -H "in1-api-key: your-api-key-string"  \
     -H "in1-calc-metrics: yes-or-no"       \
     -F submission=@/path/to/source.tif     \
     -o /path/to/result.tif                 \
     https://api.in1.ai/v1/sentinel-2

Example of super-resolve call

import in1

source = "/path/to/source.tif"
in1_api_key = "<IN1_API_KEY>"

result, profile, metrics = in1.sisr(
    source,
    api_key=in1_api_key,
    calc_metrics=True,
)
export IN1_API_KEY="<IN1_API_KEY>"

# Super resolution with metrics contained in result image
curl -H "in1-api-key: $IN1_API_KEY"     \
     -F submission=@./source.tif        \
     -o ./out-result.tif                \
     https://api.in1.ai/v1/sentinel-2
# Super resolution without metrics
curl -H "in1-api-key: $IN1_API_KEY"     \
     -H "in1-calc-metrics: no"          \
     -F submission=@./source.tif        \
     -o ./out-result.tif                \
     https://api.in1.ai/v1/sentinel-2

Endpoint for Sentinel-2 super resolution.

HTTP address

POST https://api.in1.ai/v1/sentinel-2

Parameters

Parameter Type Default Description
in1-api-key uuid The in1 API key goes here.
in1-calc-metrics boolean yes Whether or not to calculate fidelity and enhancement metrics of the supersampled image. This are included in the result image.

Request body

The submitted image as multipart form data under the field 'submission'.

Response body

In case of success, the request body contains the enhanced image. In case metrics calculation is turned on, two additional bands in the image contain the fidelity and enhancement masks, respectively.

Response codes

Code Meaning
200 Success! Body contains the super-resolved image.
401 Missing API key.
402 Insufficient credits for operation.
415 No or unreadable file sent with the request.
422 Sent image was not according to input specification.
500 The server encountered an unrecoverable error.

Demo dataset

Call definition

download_s2_dataset(
    download_dir: str = "."
) -> str
curl link-to-dataset-online-bucket \
     -o /path/to/downloaded/dataset.tar.gz

tar xzf /path/to/downloaded/dataset.tar.gz

Example of download dataset call

import in1
import geopandas as gpd

# The index is a geopackage with path, geometry,
# longitude, latitude, continent, and landcover columns
index = in1.download_s2_dataset()
index = gpd.read_file(index)
print(index.sample(10))
print(index.keys())
curl https://in1-pub.s3.eu-central-1.amazonaws.com/in1-s2-dataset.tar.gz \
     -o /tmp/in1-s2-dataset.tar.gz
tar xzf /tmp/in1-s2-dataset.tar.gz
ls in1-s2-dataset/index.gpkg in1-s2-dataset/*/*/*.tif

There is a Sentinel-2 dataset specifically designed for experimenting and playing with in1. It provides thousands of images sampled from different continents and landcovers. A georeferenced index is provided with it as well, allowing easy selection of interesting areas. Columns of interest are path, geometry, longitude, latitude, continent, and landcover.

HTTP Request

GET https://in1-pub.s3.eu-central-1.amazonaws.com/in1-s2-dataset.tar.gz

Performance metrics

Disable metrics

result, profile, _ = in1.sisr(..., calc_metrics=False)
curl -H "in1-calc-metrics: no" -o result.tif

Enable fidelity & enhancement metrics

result, profile, metrics = in1.sisr(..., calc_metrics=True)

#  Access the masks to write to files
in1.write(
    metrics["fidelity"],
    "result_fidelity.tif",
    profile
)
in1.write(
    metrics["enhancement"],
    "result_enhancement.tif",
    profile
)
# When metrics are enabled, the server returns
# fidelity and enhancement masks as part of the
# result image. These can be inspected using tools
# like QGIS or GDAL
curl -H "in1-calc-metrics: yes" -o result.tif

# Use GDAL to split metrics from the in1 result
gdal_translate -b 5 result.tif result_fidelity.tif
gdal_translate -b 6 result.tif result_enhancement.tif


Setting the request in1-calc-metrics header to yes will generate fidelity and enhancement masks as additional bands number 5 and 6 respectively. The Python client library automatically splits the in1 image and performance masks into separate variables (see in1 .sisr function definition).

Enabling metrics means in1 results will be returned more slowly, as additional calculations are performed on the in1 image. Disable metrics for speedier responses.

Fidelity

The fidelity mask measures how close the super-resolved image is to its counterpart. This is computed by downsampling the generated in1 result back to the size of the original image using an average pooling technique and calculating the pixel-wise mean-squared error between the two images. Values range between 0 and 1000 to conform with the image format. The lower the pixel value, hence, the darker the fidelity mask is, indicates greater similarity between an in1 product and its low resolution source.

Enhancement

The enhancement mask reflects the extent the in1 result diverges from its original. The low resolution source is upsampled to the size of the in1 result using nearest neighbors interpolation. Taking the pixel-wise mean-squared error between these two image highlights the increase in detail in the super-resolved image that is not present in the source image. Values also range between 0 and 1000 where higher pixel values ( i.e a lighter colored enhancement mask), reveals the areas with an increase in resolution.

Fidelity mask
Enhancement mask

Reading / writing

Call definition

# Read function
def read(
    raster_path: str
) -> Tuple[np.ndarray, rasterio.profiles.Profile]

# Write function
def write(
    raster: np.ndarray,
    raster_path: str,
    profile: Union[dict, rasterio.profiles.Profile]
)
# Using @ before a path tells cURL to read the file
# With -o cURL outputs the server's response to a file
curl -F submission=@/path/to/source.tif -o /path/to/result-example.tif ...

Example of read and write calls

source, source_profile = in1.read("source.tif")
# ... do work assigning to variables used below
in1.write(result, "result-example.tif", result_profile)
curl -F submission=@source.tif -o result-example.tif ...

The client libraries provide utility functions to read and write data. In the case of cURL we let the program do the heavy lifting.

Visualize your in1 result

We recommend QGIS to visualize the TIFFs from super-resolving and performance metrics. QGIS can be downloaded from this link.

Follow these steps for optimal visualization: