Skip to main content

Lens distortion correction for Python, a wrapper for lensfun

Project description

lensfunpy is an easy-to-use Python wrapper for the lensfun library.

API Documentation

Sample code

How to find cameras and lenses

import lensfunpy

cam_maker = 'NIKON CORPORATION'
cam_model = 'NIKON D3S'
lens_maker = 'Nikon'
lens_model = 'Nikkor 28mm f/2.8D AF'

db = lensfunpy.Database()
cam = db.find_cameras(cam_maker, cam_model)[0]
lens = db.find_lenses(cam, lens_maker, lens_model)[0]

print(cam)
# Camera(Maker: NIKON CORPORATION; Model: NIKON D3S; Variant: ;
#        Mount: Nikon F AF; Crop Factor: 1.0; Score: 0)

print(lens)
# Lens(Maker: Nikon; Model: Nikkor 28mm f/2.8D AF; Type: RECTILINEAR;
#      Focal: 28.0-28.0; Aperture: 2.79999995232-2.79999995232;
#      Crop factor: 1.0; Score: 110)

How to correct lens distortion

import cv2 # OpenCV library

focal_length = 28.0
aperture = 1.4
distance = 10
image_path = '/path/to/image.tiff'
undistorted_image_path = '/path/to/image_undist.tiff'

img = cv2.imread(image_path)
height, width = img.shape[0], img.shape[1]

mod = lensfunpy.Modifier(lens, cam.crop_factor, width, height)
mod.initialize(focal_length, aperture, distance, pixel_format=img.dtype)

undist_coords = mod.apply_geometry_distortion()
img_undistorted = cv2.remap(img, undist_coords, None, cv2.INTER_LANCZOS4)
cv2.imwrite(undistorted_image_path, img_undistorted)

It is also possible to apply the correction via SciPy instead of OpenCV. The lensfunpy.util module contains convenience functions for RGB images which handle both OpenCV and SciPy.

How to correct lens vignetting

Note that the assumption is that the image is in a linear state, i.e., it is not gamma corrected.

import lensfunpy
import imageio

db = lensfun.Database()
cam = db.find_cameras('NIKON CORPORATION', 'NIKON D3S')[0]
lens = db.find_lenses(cam, 'Nikon', 'Nikkor AF 20mm f/2.8D')[0]

# The image is assumed to be in a linearly state.
img = imageio.imread('/path/to/image.tiff')

focal_length = 20
aperture = 4
distance = 10
width = img.shape[1]
height = img.shape[0]

mod = lensfunpy.Modifier(lens, cam.crop_factor, width, height)
mod.initialize(focal_length, aperture, distance, pixel_format=img.dtype)

did_apply = mod.apply_color_modification(img)
if did_apply:
    imageio.imwrite('/path/to/image_corrected.tiff', img)
else:
    print('vignetting not corrected, calibration data missing?')

How to correct lens vignetting and TCA

Note that the assumption is that the image is in a linear state, i.e., it is not gamma corrected. Vignetting should always be corrected first before applying the TCA correction.

import imageio
import cv2
import lensfunpy

db = lensfunpy.Database()
cam = db.find_cameras('Canon', 'Canon EOS 5D Mark IV')[0]
lens = db.find_lenses(cam, 'Sigma', 'Sigma 8mm f/3.5 EX DG circular fisheye')[0]

# The image is assumed to be in a linearly state.
img = imageio.imread('/path/to/image.tiff')

focal_length = 8.0
aperture = 11
distance = 10
width = img.shape[1]
height = img.shape[0]

mod = lensfunpy.Modifier(lens, cam.crop_factor, width, height)
mod.initialize(focal_length, aperture, distance, pixel_format=img.dtype, flags=lensfunpy.ModifyFlags.VIGNETTING | lensfunpy.ModifyFlags.TCA)

# Vignette Correction
mod.apply_color_modification(img)

# TCA Correction
undist_coords = mod.apply_subpixel_distortion()
img[..., 0] = cv2.remap(img[..., 0], undist_coords[..., 0, :], None, cv2.INTER_LANCZOS4)
img[..., 1] = cv2.remap(img[..., 1], undist_coords[..., 1, :], None, cv2.INTER_LANCZOS4)
img[..., 2] = cv2.remap(img[..., 2], undist_coords[..., 2, :], None, cv2.INTER_LANCZOS4)

imageio.imwrite('/path/to/image_corrected.tiff', img)

Installation

Install lensfunpy by running:

pip install lensfunpy

64-bit binary wheels are provided for Linux, macOS, and Windows.

Installation from source on Linux/macOS

If you have the need to use a specific lensfun version or you can’t use the provided binary wheels then follow the steps in this section to build lensfunpy from source.

First, install the lensfun library on your system.

On Ubuntu, you can get (an outdated) version with:

sudo apt-get install liblensfun-dev

Or install the latest developer version from the Git repository:

git clone https://github.com/lensfun/lensfun
cd lensfun
cmake .
sudo make install

After that, install lensfunpy using:

git clone https://github.com/letmaik/lensfunpy
cd lensfunpy
pip install numpy cython
pip install .

On Linux, if you get the error “ImportError: liblensfun.so.0: cannot open shared object file: No such file or directory” when trying to use lensfunpy, then do the following:

echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/99local.conf
sudo ldconfig

The lensfun library is installed in /usr/local/lib when compiled from source, and apparently this folder is not searched for libraries by default in some Linux distributions. Note that on some systems the installation path may be slightly different, such as /usr/local/lib/x86_64-linux-gnu or /usr/local/lib64.

Installation from source on Windows

These instructions are experimental and support is not provided for them. Typically, there should be no need to build manually since wheels are hosted on PyPI.

You need to have Visual Studio installed to build lensfunpy.

In a PowerShell window:

$env:USE_CONDA = '1'
$env:PYTHON_VERSION = '3.7'
$env:PYTHON_ARCH = 'x86_64'
$env:NUMPY_VERSION = '1.14.*'
git clone https://github.com/letmaik/lensfunpy
cd lensfunpy
.github/scripts/build-windows.ps1

The above will download all build dependencies (including a Python installation) and is fully configured through the four environment variables. Set USE_CONDA = '0' to build within an existing Python environment.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

lensfunpy-1.15.0-cp312-cp312-win_amd64.whl (2.2 MB view details)

Uploaded CPython 3.12 Windows x86-64

lensfunpy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

lensfunpy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

lensfunpy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

lensfunpy-1.15.0-cp312-cp312-macosx_10_9_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.12 macOS 10.9+ x86-64

lensfunpy-1.15.0-cp311-cp311-win_amd64.whl (2.2 MB view details)

Uploaded CPython 3.11 Windows x86-64

lensfunpy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

lensfunpy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

lensfunpy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

lensfunpy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

lensfunpy-1.15.0-cp310-cp310-win_amd64.whl (2.2 MB view details)

Uploaded CPython 3.10 Windows x86-64

lensfunpy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

lensfunpy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

lensfunpy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

lensfunpy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

lensfunpy-1.15.0-cp39-cp39-win_amd64.whl (2.2 MB view details)

Uploaded CPython 3.9 Windows x86-64

lensfunpy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

lensfunpy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

lensfunpy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

lensfunpy-1.15.0-cp38-cp38-win_amd64.whl (2.2 MB view details)

Uploaded CPython 3.8 Windows x86-64

lensfunpy-1.15.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

lensfunpy-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

lensfunpy-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

File details

Details for the file lensfunpy-1.15.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 fe3c9702bd753c575690f4030250e4654b1ffd06f05ac6f206223ef7e137a72b
MD5 7faf0e2756e4a1b1a13bae0c34ebe1db
BLAKE2b-256 d9668d604a93641829fce2c84e0f4f9b9847a9a4a0181b5614da90fc29062792

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bc5980767e5f28c49a4c33165273ee8ac115d0ddcce4646d1c6215905368bb17
MD5 793948a4177b23bc2ec02305c2c1b98f
BLAKE2b-256 238cb398039a2c9b997f7046923987092e12403879dc68b16775b14c19f3b329

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 96c5431413467bec759e5fe6b7e71e5b6f3e6ea71579e1910575d01525f3a285
MD5 804753f332df4d8620f3cdb887b702c3
BLAKE2b-256 fce2b5536f43ea962ab6e6da8c7ebf03596b4b96d6a752cf5d2678072629ec28

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 73d604879e10eb945481a613cb16107c504ee001295c1e0e0f90ba802f3c7985
MD5 1d1a5d93488105a24b1f005fc265b32e
BLAKE2b-256 5f09092dd0faada6e8151098751c44773046b048452d9f13bb41ade6d663cd8d

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp312-cp312-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 b57a5f728cefb777a1b761fd4b07409bd5c59d5e0ae0e5fd57e2a8d9cb5ce232
MD5 66bd7fbf1cbafd7fabe26023328dce77
BLAKE2b-256 cb3bfc09a749e2667874aeec9af6127cb55d141229c4fbf12fa283759d5502fd

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3f7cc1e918adf6a83b4b5a5402256ee36faa12cb72aafdc619b7efc1cadd31d7
MD5 c78b94f158f99db1731746770718f7cd
BLAKE2b-256 ebf3aa5a58b46650282c6ccdfe7f05ddd4680106b82e1ea6083894735cd042dd

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 80ac051377016b062a939b7cd1026c61ea85fe2486e73974689af74cd97fdb7e
MD5 18da50fbda237cfa06b9b5515ef25f03
BLAKE2b-256 fca86618358111b9fb02731ef81cb39e851743f3ea4e17e546e257ff39787c0f

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 adb71fc82fecc7248c42de9f8e85b1a087714c6edb642c0659ec2552d25f88a0
MD5 1dbf58b340bb61dbabbd94f15690046b
BLAKE2b-256 48f7af0a56bb3dd0d7cc780a91c95470ee2397c802a5d8242b80e58a9107ee50

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0ac1b20d76a72ff6f5cff21d3290858c4eb5db6193953a29a4f27acda862b324
MD5 032681ea075326d0fd2b64bc49023697
BLAKE2b-256 70eaf9714054ef86def10dd308be53a3230c3f47d57fbbf3f941917f7c82b43f

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d8a34dbf1f28498ade92de2664b36e28b63d9457c7d9354030f8762fda6e080a
MD5 d5b2504a30dc5daf58977916c06c2aac
BLAKE2b-256 d8d5af641af8286fd472b20ad4de1b64f546abcf8bc64bb3d017b66b1ce1049d

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 122df5df56625867182239530874b382199a42ac6eaf4fe74b88b0fdaf9fc245
MD5 ee89b4a797d6828700109f47a80e66c9
BLAKE2b-256 27d50d98588efc675e315bda397b859bde63a893228a6d31294a704978b318a6

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 adfbed6e29ba833ba494e752bae386f6d84779fc2dec0e4eb60a1972c7be7d14
MD5 98a49b7afcd065bb3829ee6ef77db4a1
BLAKE2b-256 cc9a342e7d2833e305e55a60400ded0bf0bb7258db900aea7248c4da7496cbab

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 65d6813eed1b24a0a595875524e8b2b26540d65535e9f3a93118ad5d96b7f2fc
MD5 8d6cf78bfb8f6e556a16af339e3cf3ef
BLAKE2b-256 3f552c8a044f349f64d1c8f93cd2303e78109152e2c846e16048abc00bc2104a

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 88c414c456710cd6c89bd3e047eb8f122091ee59c0d449d8aa167cc05f731e8d
MD5 31ef1ca2b74684287aec87c9bb20e966
BLAKE2b-256 4f542b7e13bc51634697b13c94cced640ee92be2a51803b4fd85aeb51f07424e

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 8c436801076ad0dd04911f4bf14c5eaeacfb8ec1c9ced61e14c2ef49b39eaf2a
MD5 6e6647426eb4e636075c4694f7525633
BLAKE2b-256 a3a512414479a128d0776c243a7fce6b113c96f8c0d3b2c5a8f3967851f1da77

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 6ee2918c29ed1e9bdd0e3f47253a703b0c7a3e96163a3a42da221fb1e7800bdc
MD5 1eca83829ffbf1136716be4275e163f1
BLAKE2b-256 1cbbedb34a44d0bae90a88e7b264396643400a748e26ddb3fef4be1992c0e495

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 09b022200628a03691580192f709ef650034e04ec2c924003290d79ffd8b021a
MD5 d9a9481d2327b6d188a41997518e0165
BLAKE2b-256 640d3c90b045d21fb7b4f5f66361648670cc979613423b3d0f5c5e5fb159d118

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 cae2655ebc2dea2919757beab3f7db26cdf85fc78bf27b519b37a679d3b0dc26
MD5 53d134bd2c65410b4ea3a21483eb2663
BLAKE2b-256 53bba4c566eb0a6a42f0b43c5ed8ec7f955a47a8cafff1fe49bbe521a80b618f

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 1cf2d1f0a05475fe15e5cfd4ea3283fb7a8dcd7f7ed76a52e5a0048cdbf4e5ae
MD5 2319f9340245d23c08787f5644380cf3
BLAKE2b-256 18e5c96f812d5a6980f9f2e19bfef400dea17b65ed401fe1725340b3bf6c1cc7

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 d24285915054d173b43e0945a1112dbc65022cefee87dd979e9b5e737c47977d
MD5 e623a51d2d1f273bf7c15f1be830db97
BLAKE2b-256 9e11765d7ebac40c07a9b1906fa98cabd19f2fb0102a1a0a958929597593c436

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0f3c77ca1451064cb570fa91d1858e09c95126b8ef43610b339b02cc14427193
MD5 fc0462be56eb80e1f4b065d53c854d31
BLAKE2b-256 a9b49a48946f606d21faa2d03b155e0b654bcb0a82a5008272f520f531e998c0

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5419db6fd846542bed51d89b1b69073e7148dea41b64c0bb6d61f0c176b2cbb4
MD5 7759305fcf0d59b654f6e1f445578c69
BLAKE2b-256 6909bc6e65ce5e7523fd8745c461a0bc3db514ca46c18929a9df54ca2cd9a4d6

See more details on using hashes here.

File details

Details for the file lensfunpy-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for lensfunpy-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 3e6fa3b42cd76955288cff16d8e708fec40ad1482e1c76e4c6987d10e8a1f738
MD5 c0b5560c49016df3799c06d73b7ebcde
BLAKE2b-256 4e70a4e3b1b118b8d7df5043ed26fb237565dcf1e6fb1aaf95d636360a01b27e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page