ASAP icon indicating copy to clipboard operation
ASAP copied to clipboard

bug report

Open name-used opened this issue 8 months ago • 1 comments

There are three bugs reported as following:

  1. Color displays not accurate Image The exact color value are printed at console. And the displayed color value could be captured by screen cut-shot are marked at in the image. It seems that ASAP displays a inaccurate color value.

  2. API at "./bin/multiresolutionimageinterface.py" are not well supported. I encapsulated a tool based on this interface at this page jassor/utils/writer_asap.py. Then I found that not all optional parameters in the interface are available:

# Register LUT in _multiresolutionimageinterface:
_multiresolutionimageinterface.LUT_swigregister(LUT)
ColorType_InvalidColorType = _multiresolutionimageinterface.ColorType_InvalidColorType
ColorType_Monochrome = _multiresolutionimageinterface.ColorType_Monochrome
ColorType_RGB = _multiresolutionimageinterface.ColorType_RGB
ColorType_RGBA = _multiresolutionimageinterface.ColorType_RGBA
ColorType_Indexed = _multiresolutionimageinterface.ColorType_Indexed
DataType_InvalidDataType = _multiresolutionimageinterface.DataType_InvalidDataType
DataType_UChar = _multiresolutionimageinterface.DataType_UChar
DataType_UInt16 = _multiresolutionimageinterface.DataType_UInt16
DataType_UInt32 = _multiresolutionimageinterface.DataType_UInt32
DataType_Float = _multiresolutionimageinterface.DataType_Float
Compression_RAW = _multiresolutionimageinterface.Compression_RAW
Compression_JPEG = _multiresolutionimageinterface.Compression_JPEG
Compression_LZW = _multiresolutionimageinterface.Compression_LZW
Compression_JPEG2000 = _multiresolutionimageinterface.Compression_JPEG2000
Interpolation_NearestNeighbor = _multiresolutionimageinterface.Interpolation_NearestNeighbor
Interpolation_Linear = _multiresolutionimageinterface.Interpolation_Linear

Only "color_type in [Monochrome, RGB, RGBA]" and "data_type==UChar" are available. While I am trying to use "color_type==Indexed", I got this exit code: " Process finished with exit code -1073741819 (0xC0000005) " Similarly, use "data_type==UInt16" may get the same exit code. All bug with exit code will kill process immediately —— by cpp process —— and can not by caught anyway in python code.

Here are my test codes running with version "pip install jassor==0.6.3".

import jassor.utils as J
from jassor.components import data
import numpy as np


def main():
    path = rf'./test.tif'
    k = 512
    w = 2048
    h = 1024
    # color_type in ['INVALID', 'MONOCHROME', 'RGB', 'RGBA', 'INDEXED']
    # data_type in ['INVALID', 'UCHAR', 'UINT16', 'UINT32', 'FLOAT']
    # compression in ['RAW', 'JPEG', 'LZW', 'JPEG2000']
    # interpolation in ['LINEAR', 'NEAREST']
    with J.SlideWriter(
        output_path=path,
        tile_size=k,
        dimensions=(w, h),
        spacing=1,
        color_type='MONOCHROME',
        data_type='UINT16',
        compression='LZW',
        interpolation='NEAREST',
    ) as writer:
        for y in range(0, h, k):
            for x in range(0, w, k):
                patch = random_patch(k, 4, 255, np.uint8)[:, :, 0]
                print(f'color_{x}_{y}:{patch[0, 0]}')
                writer.write(patch, x, y)

    image = data.load(path)
    J.plot(image.thumb())


def random_patch(patch_size: int, channel: int, max_value: int, dtype: type):
    basic = np.ones((patch_size, patch_size, 1))
    color = np.random.random(channel)[None, None, :]
    patch = basic * (color * max_value).round().astype(int)
    return patch.astype(dtype)


if __name__ == '__main__':
    main()

  1. The ordering of different settings could also has influence on bug. (maybe not bug? I don't know why.)
# group 1
self._writer.setColorType(color_type_map[color_type.upper()])
self._writer.setDataType(data_type_map[data_type.upper()])
self._writer.setCompression(compression_map[compression.upper()])
self._writer.setInterpolation(interpolation_map[interpolation.upper()])
# group 2
self._writer.setTileSize(self.tile_size)
self._writer.writeImageInformation(self.W, self.H)
pixel_size_vec = mir.vector_double()
pixel_size_vec.push_back(self.spacing)
pixel_size_vec.push_back(self.spacing)
self._writer.setSpacing(pixel_size_vec)

Exchange the order of group 1 and group 2 can also cause bug exit code.

name-used avatar May 15 '25 06:05 name-used

Additional, I tryed to write color_type==RGBA with this code:

import jassor.utils as J
from jassor.components import data
import numpy as np


def main():
    path = rf'./test.tif'
    k = 512
    w = 2048
    h = 1024
    # color_type in ['INVALID', 'MONOCHROME', 'RGB', 'RGBA', 'INDEXED']
    # data_type in ['INVALID', 'UCHAR', 'UINT16', 'UINT32', 'FLOAT']
    # compression in ['RAW', 'JPEG', 'LZW', 'JPEG2000']
    # interpolation in ['LINEAR', 'NEAREST']
    with J.SlideWriter(
        output_path=path,
        tile_size=k,
        dimensions=(w, h),
        spacing=1,
        color_type='RGBA',
        data_type='UCHAR',
        compression='LZW',
        interpolation='NEAREST',
    ) as writer:
        for y in range(0, h, k):
            for x in range(0, w, k):
                patch = random_patch(k, 4, 255, np.uint8)
                patch[:, :, 3] = 120
                print(f'color_{x}_{y}:{patch[0, 0]}')
                writer.write(patch, x, y)

    slide = data.load(path)
    thumb = slide.thumb(level=0)
    for y in range(0, h, k):
        for x in range(0, w, k):
            print(thumb[y, x])
    J.plot(thumb)


def random_patch(patch_size: int, channel: int, max_value: int, dtype: type):
    basic = np.ones((patch_size, patch_size, 1))
    color = np.random.random(channel)[None, None, :]
    patch = basic * (color * max_value).round().astype(int)
    return patch.astype(dtype)


if __name__ == '__main__':
    main()

Then I got this:

color_0_0:[219 223  76 120]
color_512_0:[141  67   8 120]
color_1024_0:[138  85 154 120]
color_1536_0:[111 139 123 120]
color_0_512:[106 133  22 120]
color_512_512:[145 201   4 120]
color_1024_512:[171  35  39 120]
color_1536_512:[ 24 121  18 120]
Total time was 89
Total reading time was 0
Total base writing time was 24
Total pyramid downsampling time was 0
Total pyramid writing time was 65
Total time determining min/max was 5
TIFFReadDirectory: Warning, Sum of Photometric type-related color channels and ExtraSamples doesn't match SamplesPerPixel. Defining non-color channels as ExtraSamples..
TIFFReadDirectory: Warning, Sum of Photometric type-related color channels and ExtraSamples doesn't match SamplesPerPixel. Defining non-color channels as ExtraSamples..
TIFFReadDirectory: Warning, Sum of Photometric type-related color channels and ExtraSamples doesn't match SamplesPerPixel. Defining non-color channels as ExtraSamples..
TIFFReadDirectory: Warning, Sum of Photometric type-related color channels and ExtraSamples doesn't match SamplesPerPixel. Defining non-color channels as ExtraSamples..
[209 217 161 120]
[ 43 142  17 120]
[ 37 180  71 120]
[235  39   5 120]
[225  26  46 120]
[ 52 171   8 120]
[107  74  82 120]
[ 51   1  38 120]

Process finished with exit code 0

I found that if channel_A eq 255, then RGB is corrected. If channel_A eq 0, then RGB is writen as BGR. If channel_A in range (0, 255), then RGB are all discorrect values. So it seems only color_type in [MONOCHROME, RGB] are available.

name-used avatar May 15 '25 06:05 name-used