zeiss-microscopy / libCZI

Open Source Cross-Platform C++ library to read CZI image files
GNU General Public License v3.0
70 stars 19 forks source link

CZIcmd: Colour Channel order reversed for 10 bit and 12 bit images. #36

Closed ntrahearn closed 6 years ago

ntrahearn commented 6 years ago

I've been using CZIcmd lately and I've found it to be a really nice tool for automatically retrieving image data as it appears in Zen. Though I've found something strange happening when I give it images that were scanned with 10 bit or 12 bit colour. The H&E came out looking reddish, like this:

10bitexample1

I compared this with what I saw in Zen and it was clearly different:

10bitexample2

Anyway, long story short, I realised that the colour channels were in reverse order for some reason. So if I swapped the red and blue colour channels over then that fixed everything.

10bitexample3

I've not used libCZI directly, so I don't know if this is an issue with just CZIcmd or the underlying library.

ptahmose commented 6 years ago

Could you provide that very CZI-file (and maybe the CZICmd-command-line you used)?

harukizaemon commented 6 years ago

AFAIK, the "reversed" ordering is 100% correct. The code explicitly describes the channels as being BGR not RGB:

enum class PixelType : std::uint8_t
{
    Gray8 = 0,
    Gray16 = 1,
    Gray32Float = 2, Bgr24 = 3,
    Bgr48 = 4,
    Bgr96Float = 8,
    Bgra32 = 9,
    Gray64ComplexFloat = 10,
    Bgr192ComplexFloat = 11,
    Gray32 = 12,
    Gray64Float = 13,
};

https://github.com/zeiss-microscopy/libCZI/blob/master/Src/libCZI/CziStructs.h#L38

ntrahearn commented 6 years ago

Perhaps I'm misunderstanding your point, harukizaemon, but I wouldn't agree with that.

First, this only happens with 10 or 12 bit images, 8 bit images come out "normal". So unless there's something specific about 8 bit vs. 10/12 bit (e.g. one is RGB and the other is BGR, perhaps), then I don't see why it'd be this way for only some bitnesses.

Second, even if this was the case surely CZIcmd should account for that difference, as it outputs the images as PNG files. PNG has a prescribed channel order: RGB (plus A, if appropriate). So saving a PNG with the channels in BGR order is always going to be incorrect.

I'd be happy to share a file demonstrating this issue. Is there a designated place where I can upload this image?

harukizaemon commented 6 years ago

Hey @ntrahearn, Sorry for the ambiguity. I'm not asserting there isn't a bug or an inconsistency in implementation. I'm only observing that the code explicitly describes the order of channels for those data types as BGR, and every use-case I've encountered to-date is consistent with that.

ptahmose commented 6 years ago

I'd be happy to share a file demonstrating this issue. Is there a designated place where I can upload this image?

No, no designated place. Putting it at OneDrive or Google-Drive would be fine if it is not too large. If it is, maybe it is possible to "cut out" a smaller piece (provided that the problem can be reproduced with it). Thanks!

ntrahearn commented 6 years ago

Okay, I've just scanned one of Zeiss' demo slides at 8-bit, 10-bit, and 12-bit. The files can be accessed here:

https://drive.google.com/drive/folders/1UsO8qNYTRxdyF28oWwNuaOdnDWnYjYAk

Also in that folder are 3 images, each extracted using CZIcmd, showing a sub-region of the slide at the different colour depths. For full clarity, this is the command I used to extract one of these images:

CZIcmd --command ChannelComposite --background 1 --rect rel\(50000,50000,1000,1000\) --source 12bit.czi --output out12

ptahmose commented 6 years ago

I had a brief look - and it seems that the problem is with the JPGXR-decoder (your files are JPGXR-compressed). The decoder (both the WIC-codec and the JxrDecode-library-codec) cannot directly output BGR48, so the data needs to be converted I suppose. With uncompressed BGR48-CZIs it works ok for me. I'll try to provide a patch asap.

zeissmicroscopy commented 6 years ago

...should be fixed now (for both codec-implementations). Note that you can choose to use the Windows-provided "WIC-codec" with the command-line option "-j WIC" (or "--jpgxrcodec WIC") - which might be faster or better. However, I never did a benchmark. Note that the binaries in the repository have not yet been updated.