Code Monkey home page Code Monkey logo

rio-hist's Introduction

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.

rio-hist's People

Contributors

perrygeo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rio-hist's Issues

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'.

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?

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!

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)

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!

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

Match multiple references

It's possible that a single reference might be biased; try a model that matches to an averaged histogram across several reference layers.

Handle nodata masks

Currently nodata value is treated as any other value. Nodata needs to be masked and discarded from the cdf.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.