Histogram matching plugin for rasterio

Overview

Build Status Coverage Status

rio-hist

Histogram matching plugin for rasterio.

Provides a CLI and python module for adjusting colors based on histogram matching in a variety of colorspaces.

Example

We have a source image that we want to alter. We have a reference image with a histogram that we like. The goal is to adjust the values of the source image so that its histogram matches that of the reference.

The matching directly in the default RGB colorspace does not always give the best results. So for this example, we'll adjust based on the Lightness and Chroma in LCH colorspace.

$ rio hist -c LCH -b 1,2 --plot source.tif reference.tif output.tif

This will give us a new output.tif that matches the histogram of reference. And the --plot option also allows us to see some diagnostic plots to inspect the results and the cumulative distribution functions of the matching process.

CLI docs

$ rio hist --help
Usage: rio hist [OPTIONS] SRC_PATH REF_PATH DST_PATH

  Color correction by histogram matching

Options:
  -c, --color-space [RGB|LCH|LAB|Lab|LUV|XYZ]
                                  Colorspace
  -b, --bands TEXT                comma-separated list of bands to match
                                  (default 1,2,3)
  -m, --match-proportion FLOAT    Interpolate values between source and
                                  reference histogram. 1.0 (default) is full
                                  match, 0.0 is no match
  --plot                          create a <basename>_plot.png with diagnostic
                                  plots
  -v, --verbose
  --co NAME=VALUE                 Driver specific creation options.See the
                                  documentation for the selected output driver
                                  for more information.
  --help                          Show this message and exit.

Python docs

rio_hist.match.histogram_match is the main entry point and operates on a single band.

rio_hist.utils has some interesting functions that may be useful in other contexts.

Comments
  • Which color spaces are useful for histogram matching?

    Which color spaces are useful for histogram matching?

    Currently I'm using skimage for all but the LCH colorspace (which is implemented directly in rio-color)

    Related to https://github.com/mapbox/rio-color/issues/28, we might want to make rio-color a more full-fledged colorspace module.

    Let's identify which color spaces are useful for the purposes of histogram matching to guide that decision.

    /cc @celoyd @virginiayung

    question 
    opened by perrygeo 9
  • Attribute Error

    Attribute Error

    Ran successfully on your test data 1 but not test data 2 (Andros Island, The Bahamas). I tried to run on my own satellite imagery and got the same error as test data 2: AttributeError: "DatasetReader' object has no attribute 'mask flags'.

    opened by geointerest 4
  • Regarding creation_options

    Regarding creation_options

    Beautiful approach to histogram matching by the way! I am trying to integrate histogram matching into a personal project and am running into an error. from rio_hist.match import hist_match_worker hist_match_worker(mypath, myref, mypath_out, 1,creation_options, '1,2', 'LCH', None) What are the creation_options in this case? Are they used for writing and reading the profiles in rasterio? Are there any options to send to this command to make this work? I tried a similar approach to how you tested the cli but with no success. Thank you!

    opened by MostafaOkasha 3
  • LCH space and 16-bit to 8-bit match

    LCH space and 16-bit to 8-bit match

    Here is a basic implementation of matching 16-bit RGB image to an 8-bit target image in LCH space. The image is then saved back in 16-bit RGB with the bit-depth corresponding to that of the sensor and a black point offset to allow further adjustmests without too much clipping of shadows or highlights. The RGB->LCH->RGB transform is lossy in colour for 8-bit outputs, 16-bit preserves the LCH space better and has less quantization. The colour space transfroms are all derived from sckit-image.

       from skimage.color import rgb2lab, lab2lch, lch2lab, lab2rgb
        with rasterio.open(test_image) as src:
            rgb_src = src.read()
            profile = src.profile
        
        with rasterio.open(sample_tif) as target:
            rgb_sample = target.read()[:3]
        
        float_rgb_src = rgb_src/(2**16)
        float_rgb_sample = rgb_sample/(2**8)
        rgb_src_image = reshape_as_image(float_rgb_src)
        rgb_sample_image = reshape_as_image(float_rgb_sample)
        
        lch_src = lab2lch(rgb2lab(rgb_src_image))
        lch_sample = lab2lch(rgb2lab(rgb_sample_image))
        
        lch_target = lch_src.copy()
        """Adjust Luminance"""
        lch_target[:,:,0] = hist_match(lch_src[:,:,0],lch_sample[:,:,0])
        """Adjust Chroma"""
        lch_target[:,:,1] = hist_match(lch_src[:,:,1],lch_sample[:,:,1])
        rgb_target_image = lab2rgb(lch2lab(lch_target))
        
        float_rgb_target = reshape_as_raster(rgb_target_image)
        rgb_target = float_rgb_target*(2**bit_depth)+ black_pt
    
    opened by whatnick 1
  • partial histogram matching

    partial histogram matching

    Specifying --match-proportion 1.0 will do a full histogram match (the default)

    Specifying --match-proportion 0.0 will effectively not change anything.

    For every value in between, it moves the source closer to the reference by linear interpolation on the cumulative distribution.

    out

    Resolves #8

    todo

    • [x] try with some other scenes; i'm sure there are edge cases that don't work well.
    • [x] try with other colorspaces. only RGB so far.
    • [ ] unit and integration tests

    cc @celoyd @virginiayung

    opened by perrygeo 1
  • “LAB” → “Lab”

    “LAB” → “Lab”

    The colorspace is called Lab, sic, and spelling it LAB is likely to trip up people who are familiar with it.

    Because the colorspace string is downcased internally, this is entirely cosmetic.

    opened by celoyd 1
  • How to matching the histogram

    How to matching the histogram

    Well, the results and the analyses looks so good. But I wonder how to matching the histogram or if there are any papers described this algorithm. Thanks!

    wontfix 
    opened by elvindp 0
  • Drop HSV

    Drop HSV

    Hue-Saturation-Value colorspace has numerous problems for analytical purposes which are well articulated here: https://en.wikipedia.org/wiki/HSL_and_HSV#Disadvantages

    TL;DR; there are quantifiably better alternatives (Lab, Lch and Luv) so why bother with HSV

    Dropping HSV means we can drop skimage too!

    opened by perrygeo 0
  • RGBA and masked rasters

    RGBA and masked rasters

    Currently rio-hist can handle nodata in RGB rasters.

    We also need to support

    • RGBA Alpha bands
    • internal GDAL masks
    • external GDAL masks (.msk sidecar)
    bug 
    opened by perrygeo 0
  • Account for not-unique source masked values

    Account for not-unique source masked values

    Suppose a user inputs an array where masked values are not all unique (e.g. user is matching histograms for .tif red raster band with nodata value of 0. When rastertio.open() reads the .tif, machine epsilon may code some zeros a little bit off, like say 0.00000000001. Then the mask will cover 0 and 0.00000000001). Then, before the insertion of this edit, mask_index[0] would contain more than one value, and everything breaks. My edit replaces all masked values with np.nan up front to ensure np.unique (line 53) records only one masked value, thus preserving the mask_index[0] system below.

    opened by ceramic-mug 0
  • For different reference image?

    For different reference image?

    Thank you very much for this nice repo. I am also working on normalization. My problem is the reference image. If the content of the reference image is different with the source image, how can I normalize brightness/illumination using histogram matching?

    opened by AI-ML-Enthusiast 0
  • added support for input images with float datatype

    added support for input images with float datatype

    usage of np.iinfo forces the user to use only arrays (images) with integer data type in cs_forward function in rio_hist/utils.py. So, a small change was added to the same function which will use np.finfo if the input arr is float and use np.iinfo otherwise

    opened by VaasuDevanS 0
Owner
Mapbox
Mapbox is the location data platform for mobile and web applications. We're changing the way people move around cities and explore our world.
Mapbox
User friendly Rasterio plugin to read raster datasets.

rio-tiler User friendly Rasterio plugin to read raster datasets. Documentation: https://cogeotiff.github.io/rio-tiler/ Source Code: https://github.com

null 372 Dec 23, 2022
Cloud Optimized GeoTIFF creation and validation plugin for rasterio

rio-cogeo Cloud Optimized GeoTIFF (COG) creation and validation plugin for Rasterio. Documentation: https://cogeotiff.github.io/rio-cogeo/ Source Code

null 216 Dec 31, 2022
Rasterio reads and writes geospatial raster datasets

Rasterio Rasterio reads and writes geospatial raster data. Geographic information systems use GeoTIFF and other formats to organize and store gridded,

Mapbox 1.9k Jan 7, 2023
Read and write rasters in parallel using Rasterio and Dask

dask-rasterio dask-rasterio provides some methods for reading and writing rasters in parallel using Rasterio and Dask arrays. Usage Read a multiband r

Dymaxion Labs 85 Aug 30, 2022
A light-weight, versatile XYZ tile server, built with Flask and Rasterio :earth_africa:

Terracotta is a pure Python tile server that runs as a WSGI app on a dedicated webserver or as a serverless app on AWS Lambda. It is built on a modern

DHI GRAS 531 Dec 28, 2022
How to use COG's (Cloud optimized GeoTIFFs) with Rasterio

How to use COG's (Cloud optimized GeoTIFFs) with Rasterio According to Cogeo.org: A Cloud Opdtimized GeoTIFF (COG) is a regular GeoTIFF file, aimed at

Marvin Gabler 8 Jul 29, 2022
Color correction plugin for rasterio

rio-color A rasterio plugin for applying basic color-oriented image operations to geospatial rasters. Goals No heavy dependencies: rio-color is purpos

Mapbox 111 Nov 15, 2022
User friendly Rasterio plugin to read raster datasets.

rio-tiler User friendly Rasterio plugin to read raster datasets. Documentation: https://cogeotiff.github.io/rio-tiler/ Source Code: https://github.com

null 372 Dec 23, 2022
Cloud Optimized GeoTIFF creation and validation plugin for rasterio

rio-cogeo Cloud Optimized GeoTIFF (COG) creation and validation plugin for Rasterio. Documentation: https://cogeotiff.github.io/rio-cogeo/ Source Code

null 216 Dec 31, 2022
This plugin plots the time you spent on a tag as a histogram.

This plugin plots the time you spent on a tag as a histogram.

Tom Dörr 7 Sep 9, 2022
Rasterio reads and writes geospatial raster datasets

Rasterio Rasterio reads and writes geospatial raster data. Geographic information systems use GeoTIFF and other formats to organize and store gridded,

Mapbox 1.9k Jan 7, 2023
Read and write rasters in parallel using Rasterio and Dask

dask-rasterio dask-rasterio provides some methods for reading and writing rasters in parallel using Rasterio and Dask arrays. Usage Read a multiband r

Dymaxion Labs 85 Aug 30, 2022
A light-weight, versatile XYZ tile server, built with Flask and Rasterio :earth_africa:

Terracotta is a pure Python tile server that runs as a WSGI app on a dedicated webserver or as a serverless app on AWS Lambda. It is built on a modern

DHI GRAS 531 Dec 28, 2022
How to use COG's (Cloud optimized GeoTIFFs) with Rasterio

How to use COG's (Cloud optimized GeoTIFFs) with Rasterio According to Cogeo.org: A Cloud Opdtimized GeoTIFF (COG) is a regular GeoTIFF file, aimed at

Marvin Gabler 8 Jul 29, 2022
Types for the Rasterio package

types-rasterio Types for the rasterio package A work in progress Install Not yet published to PyPI pip install types-rasterio These type definitions

Kyle Barron 7 Sep 10, 2021
Image histogram remapping

Hmap An image histogram remapping script written in Python 2.7 by Anthony Kesich and Ross Goodwin. Changes source image so that source image's histogr

Ross Goodwin 199 Nov 19, 2022
Python histogram library - histograms as updateable, fully semantic objects with visualization tools. [P]ython [HYST]ograms.

physt P(i/y)thon h(i/y)stograms. Inspired (and based on) numpy.histogram, but designed for humans(TM) on steroids(TM). The goal is to unify different

Jan Pipek 120 Dec 8, 2022
Histogram specification using openCV in python .

histogram specification using openCV in python . Have to input miu and sigma to draw gausssian distribution which will be used to map the input image . Example input can be miu = 128 sigma = 30

Tamzid hasan 6 Nov 17, 2021
A conda-smithy repository for boost-histogram.

The official Boost.Histogram Python bindings. Provides fast, efficient histogramming with a variety of different storages combined with dozens of composable axes. Part of the Scikit-HEP family.

conda-forge 0 Dec 17, 2021
Histogramming for analysis powered by boost-histogram

Hist Hist is an analyst-friendly front-end for boost-histogram, designed for Python 3.7+ (3.6 users get version 2.4). See what's new. Installation You

Scikit-HEP Project 97 Dec 25, 2022