2017-12-18 23:15 CET

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0001079OTB-libGeneralpublic2017-04-13 16:45
Reportergrizonnetm 
Assigned Togrizonnetm 
PriorityhighSeveritymajorReproducibilityalways
StatusclosedResolutionfixed 
Summary0001079: OTB does not handle tif with NBITS=1 properly
DescriptionTif format allows to store image on arbitrary number of bands less than 8 bits (1 to 7): http://www.gdal.org/frmt_gtiff.html
(The apparent pixel is 'Byte')

You can generate tif coded on 1 bit using OTB and extended file (?&gdal:co:NBITS=1)

GDALImageIO does not read it properly as it interprets the image as a 4 bands image with max value equal to 255 (and not 1).
Steps To Reproduce- create an image with 2 pixels with value 0 and 1 (otb::Image<unsigned char,2>).

- Write it to tif using NBITS=1 (?&gdal:co:NBITS=1)

- Use the convert application to convert it back to tif (coded on 8 bits):

otbcli_Convert -in input.tif -out output.tif uint8

- gdalinfo -stats output.tif

It gives:

Size is 1, 2
Coordinate System is `'
Origin = (-0.500000000000000,-0.500000000000000)
Pixel Size = (1.000000000000000,1.000000000000000)
Image Structure Metadata:
  INTERLEAVE=PIXEL
Corner Coordinates:
Upper Left ( -0.5000000, -0.5000000)
Lower Left ( -0.5000000, 1.5000000)
Upper Right ( 0.5000000, -0.5000000)
Lower Right ( 0.5000000, 1.5000000)
Center ( 0.0000000, 0.5000000)
Band 1 Block=1x2 Type=Byte, ColorInterp=Red
  Minimum=0.000, Maximum=255.000, Mean=127.500, StdDev=127.500
  Mask Flags: PER_DATASET ALPHA
  Metadata:
    STATISTICS_MAXIMUM=255
    STATISTICS_MEAN=127.5
    STATISTICS_MINIMUM=0
    STATISTICS_STDDEV=127.5
Band 2 Block=1x2 Type=Byte, ColorInterp=Green
  Minimum=0.000, Maximum=255.000, Mean=127.500, StdDev=127.500
  Mask Flags: PER_DATASET ALPHA
  Metadata:
    STATISTICS_MAXIMUM=255
    STATISTICS_MEAN=127.5
    STATISTICS_MINIMUM=0
    STATISTICS_STDDEV=127.5
Band 3 Block=1x2 Type=Byte, ColorInterp=Blue
  Minimum=0.000, Maximum=255.000, Mean=127.500, StdDev=127.500
  Mask Flags: PER_DATASET ALPHA
  Metadata:
    STATISTICS_MAXIMUM=255
    STATISTICS_MEAN=127.5
    STATISTICS_MINIMUM=0
    STATISTICS_STDDEV=127.5
Band 4 Block=1x2 Type=Byte, ColorInterp=Alpha
  Minimum=255.000, Maximum=255.000, Mean=255.000, StdDev=0.000
  Metadata:
    STATISTICS_MAXIMUM=255
    STATISTICS_MEAN=255
    STATISTICS_MINIMUM=255
    STATISTICS_STDDEV=0
Additional InformationOne possible reason is that OTB is perhaps interpreting color table information available in the input image.

gdalinfo -stats input.tif

Size is 1, 2
Coordinate System is `'
Origin = (-0.500000000000000,-0.500000000000000)
Pixel Size = (1.000000000000000,1.000000000000000)
Image Structure Metadata:
  COMPRESSION=DEFLATE
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left ( -0.5000000, -0.5000000)
Lower Left ( -0.5000000, 1.5000000)
Upper Right ( 0.5000000, -0.5000000)
Lower Right ( 0.5000000, 1.5000000)
Center ( 0.0000000, 0.5000000)
Band 1 Block=1x2 Type=Byte, ColorInterp=Palette
  Min=0.000 Max=1.000
  Minimum=0.000, Maximum=1.000, Mean=0.500, StdDev=0.500
  Metadata:
    STATISTICS_MAXIMUM=1
    STATISTICS_MEAN=0.5
    STATISTICS_MINIMUM=0
    STATISTICS_STDDEV=0.5
  Image Structure Metadata:
    NBITS=1
  Color Table (RGB with 2 entries)
    0: 0,0,0,255
    1: 255,255,255,255
TagsNo tags attached.
Attached Files
  • ? file icon img.tif (308 bytes) 2015-10-07 17:28

-Relationships
+Relationships

-Notes

~0003030

gpasero (administrator)

I don't think this bug is caused by the NBITS=1. As stated in GDAL GeoTIFF documentation, when NBTIS=1..7, the apparent pixel type is Byte, so in otbGDALImageIO.cxx, it should be seen as any other Byte image. The explanation of the color table is more likely.

~0003032

grizonnetm (administrator)

You're right the cause is the color table. GDAL automatically create a palette in this case (ColorInterp=Palette).

Are we interpreting this info correctly?

QGIS also recognize the input image type as Palette but gives the "right" value when I access pixel info (0 and 1 in this case)

I've attached the image (2 pixels)

~0003033

gpasero (administrator)

I agree, GDAL automatically set a palette for color interpretation. In OTB, when a palette is available and pixel type is Byte, the image is automatically read as a color image (using the palette). Perhaps this behaviour should be restricted. Palette could be activated using an extended filename ?

~0003037

grizonnetm (administrator)

OTB should be able to access both pixel values (encoded and indexed value).

Agree with you also that the default (==automatic) mode should return the value in the file and that the palette can be activated (extended filename sounds as the good level to do this)

~0003042

gpasero (administrator)

Ok with you. The only difficulty here is that the palette is handled directly in GDALImageIO, whereas the extended filename is mostly handled in ImageFileReader.
I know that GDAL is handling 99% of the images but the palette interpretation may not be specific to GDAL.

I would suggest :
- disable palette conversion in GDALImageIO (the comments in this part of the code are rather careful)
- GDALImageIO should report the palette to ImageFileReader (as a metadata ? a kind of LUT ?).
- ImageFileReader should use a kind of adapter filter to convert the mono image into color.

~0003971

grizonnetm (administrator)

Did we finally converge to a fix for this issue?

Disabling palette conversion by default seems rather obvious (and easy) to do but it is not clear for me if providing a mechanism to

Perhaps an other option is to follow recent changes in ITK where they give the possibility to activate palette interpretation in the API but only in the ImageIO:

http://review.source.kitware.com/#/c/22005/

~0004122

grizonnetm (administrator)

fixed in develop (will be released in 6.0)
+Notes

-Issue History
Date Modified Username Field Change
2015-10-06 15:59 grizonnetm New Issue
2015-10-06 17:54 gpasero Note Added: 0003030
2015-10-07 17:27 grizonnetm Note Added: 0003032
2015-10-07 17:28 grizonnetm File Added: img.tif
2015-10-12 14:25 gpasero Note Added: 0003033
2015-10-12 14:25 gpasero Assigned To => gpasero
2015-10-12 14:25 gpasero Status new => confirmed
2015-10-16 14:23 grizonnetm Note Added: 0003037
2015-10-16 18:52 gpasero Note Added: 0003042
2015-11-10 10:31 julien Priority high => urgent
2017-01-30 08:51 grizonnetm Note Added: 0003971
2017-01-30 16:17 julien Priority urgent => high
2017-04-13 16:45 grizonnetm Note Added: 0004122
2017-04-13 16:45 grizonnetm Status confirmed => closed
2017-04-13 16:45 grizonnetm Assigned To gpasero => grizonnetm
2017-04-13 16:45 grizonnetm Resolution open => fixed
+Issue History