Giter Site home page Giter Site logo

icc-profiles's Introduction

Exploring ICC Profiles

This repo explores how to apply ICC profiles to images in both Python and Java.

It is aimed mostly at pathology applications.

For more info, see @choosehappy's post at http://www.andrewjanowczyk.com/application-of-icc-profiles-to-digital-pathology-images/ - which is also the inspiration for the Python bit.

ICC profiles are known to be a thing with Aperio SVS images, and they are applied by default in the ImageScope viewer - but not applied by default in other common software... such as QuPath (at least not in the current version 0.3.2). As a result, the colors can appear differently.

The sample images here are from https://openslide.org (CMU-1.svs). I opened them in ImageScope, then exported them using three approaches:

  • Apply the ICC profile
  • Embed the ICC profile
  • Ignore the ICC profile

The aim is to compare between these, and ideally figure out how to use the embedded ICC Profile to get a similar result to the one where it was applied at export.

Python

The python code is shown in ICC Profiles in Python.ipynb.

In summary: reading the 'ignore' and 'embedded' images with imageio give the same pixel data; 'applied' is different.

However, the ICC profile can be extracted from the 'embedded' image and converted to a transform using Pillow. Applying this transform to the 'ignore' or 'embedded' image gets a result that is very similar image to 'applied' (but not identical).

Java

The Java code is in the app directory, and runnable with

gradlew run

The full output is shown at the bottom, but the main points are:

  • When reading with ImageIO, 'applied' and 'embedded' give similar (not identical) images - any embedded ICC profile is used while the image is being read
    • This is not necessarily the case when reading the same image with other software, e.g. using Bio-Formats to read the same images doesn't appear to use the embedded ICC profile
  • If the the ICC profile is extracted, it can be applied later using a ColorConvertOp - but be careful!
    • If providing a BufferedImage as input, the output image is different from what is expected
    • If providing a WriteableRaster as input and constructing a ColorModel manually, the image created by combining those can be the same as the result given by ImageIO when reading the image with the embedded transform
// Create a color convert op to apply the transform
ICC_Profile iccTarget = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
ColorConvertOp op = new ColorConvertOp(
        new ICC_Profile[] {iccSource, iccTarget},
        null
);

// Try applying the transform to the buffered image
// THIS *DIDN'T* WORK FOR ME!
BufferedImage imgTransformed = op.filter(img, null);

// Try applying the transform to the raster only
// THIS *DID* WORK FOR ME!
BufferedImage imgTransformedRaster =
        new BufferedImage(
                new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), false, false,
                        ColorModel.OPAQUE, DataBuffer.TYPE_BYTE),
                op.filter(img.getRaster(), null),
                false,
                null
        );

Basically, it's not straightforward:

  1. There's a risk that the ICC profile has already been used, depending upon how the image was read
  2. If the ICC profile wasn't used, there's a risk that it gives unexpected results because ColorConvertOp can give a different outcome depending upon whether it's provided with a BufferedImage or a WritableRaster

Java output

-----
CMU-Apply.tif and CMU-Embed.tif are different
   Different pixels: 8.5 %
   Mean: -0.0, Min: -3.0, Max: 7.0, MAD: 0.04
-----
CMU-Apply.tif and CMU-Ignore.tif are different
   Different pixels: 99.9 %
   Mean: 3.8, Min: -62.0, Max: 31.0, MAD: 5.16
-----
CMU-Apply.tif and TRANSFORMED are different
   Different pixels: 100.0 %
   Mean: -1.4, Min: -84.0, Max: 32.0, MAD: 8.59
-----
CMU-Apply.tif and TRANSFORMED-RASTER are different
   Different pixels: 8.5 %
   Mean: -0.0, Min: -3.0, Max: 7.0, MAD: 0.04
-----
-----
CMU-Embed.tif and CMU-Ignore.tif are different
   Different pixels: 100.0 %
   Mean: 3.8, Min: -62.0, Max: 32.0, MAD: 5.17
-----
CMU-Embed.tif and TRANSFORMED are different
   Different pixels: 100.0 %
   Mean: -1.4, Min: -84.0, Max: 32.0, MAD: 8.59
-----
CMU-Embed.tif and TRANSFORMED-RASTER are identical
-----
-----
CMU-Ignore.tif and TRANSFORMED are different
   Different pixels: 100.0 %
   Mean: -5.3, Min: -40.0, Max: 41.0, MAD: 9.06
-----
CMU-Ignore.tif and TRANSFORMED-RASTER are different
   Different pixels: 100.0 %
   Mean: -3.8, Min: -32.0, Max: 62.0, MAD: 5.17
-----
-----
TRANSFORMED and TRANSFORMED-RASTER are different
   Different pixels: 100.0 %
   Mean: 1.4, Min: -32.0, Max: 84.0, MAD: 8.59
-----

icc-profiles's People

Contributors

petebankhead avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Forkers

veyselolgun

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.