Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for robust plotting of RGB images #71

Open
robintw opened this issue Nov 14, 2020 · 1 comment
Open

Add support for robust plotting of RGB images #71

robintw opened this issue Nov 14, 2020 · 1 comment
Labels
enhancement New feature or request

Comments

@robintw
Copy link

robintw commented Nov 14, 2020

Firstly, thanks for this wonderful library. If it had been around during my PhD it would have saved me a lot of time!

My PhD was in satellite imaging, and I still work in that area today. When visualising satellite images, we often want to apply a robust image stretch (eg. a 2%-98% percentile stretch) to an RGB image. The way this works is by doing a stretch on each band separately, and then combining them together.

This doesn't seem to be possible with seaborn_image at the moment: I notice that in

robust = False # set robust to False if RGB image
, robust is set to False if it's a RGB image.

I've had a bit of a poke around in the code, and it seems like the robust image display is done using vmax and vmin parameters to matplotlib. It looks like those probably don't support doing a different stretch on each band - so it would probably have to be done manually, making it a bit more difficult.

Anyway, I might have time to play around with this sometime (depending on work constraints) - would this be something you'd be interested in? It might require a change to how the library deals with robust plotting.

@SarthakJariwala
Copy link
Owner

Thank you!

Your interpretation of the robust parameter is correct. It is not transforming the data but merely altering the colormap vmin and vmax display. The primary intention behind robust is to ignore any outliers.

I think what you propose would be of interest, perhaps as a separate stretch or scale_int parameter which performs the intensity rescale based on the percentile specified to the perc parameter, instead of changing robust plotting.

For the time being, there is an existing workaround. You can map a function to your input image using the map_func parameter in imgplot(). For instance, for the specific case you mentioned (as I understand it), you could try the following -

from skimage.exposure import rescale_intensity
import numpy as np
import seaborn_image as isns

def stretch(rgb_data, p=(2,98)):
    rescaled_data = np.zeros_like(rgb_data)
    for i in range(rgb_data.shape[-1]):
        _lower, _upper = np.nanpercentile(rgb_data[:, :, i], p)
        rescaled_data[:, :, i] = exposure.rescale_intensity(rgb_data[:, :, i], in_range=(_lower, _upper))
    return rescaled_data

ax = isns.imgplot(rgb_data, map_func=stretch, p=(2,98))

Additionally, if you are interested in viewing the individual bands/channels, you can try ImageGrid() :

g = isns.ImageGrid(rgb_data, robust=True, perc=(2,98))

Here, the robust parameter with be applied to all the individual bands and displayed separately. You can also use the map_func parameter to map your function of interest :

g = isns.ImageGrid(rgb_data, map_func=stretch, p=(2,98))

Overall, I agree that having an easier way to re-scale the intensity using a stretch or scale_int parameter would be helpful.

@SarthakJariwala SarthakJariwala added the enhancement New feature or request label Nov 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants