0

My final goal is to implement cloud detection algorithm with C++. However, I faced a problem.

I have an issue with extracting information from pixels. For data pre-processing, SNAP was used and I can see a lot of information there for a given pixel (longitude, latitude, band value, etc.).

Pixel Info in SNAP

The problem arises when I export the image as a TIFF file. To deal with it, I used LibTIFF library. However, I do not really know how to extract specific information about a given pixel. Currently, I have a standard code given in LibTIFF documentation to loop through all the pixels of an image and print out its value. Unfortunately, the values I get do not make sense.

TIFF* tif = TIFFOpen(filename, "r");
if (tif) {
    uint32 imagelength;
    double * buf;
    tsize_t scanline;
    uint32 row;
    uint32 i;
    tsize_t y;

    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength);
    scanline = TIFFScanlineSize(tif);
    buf = (double *) _TIFFmalloc(scanline);
    for (row = 0; row < imagelength; row++) {
        int n = TIFFReadScanline(tif, buf, row);

        for (y = 0; y < scanline; y++) {
            cout << "Row: " << row << " y: " << y << " " << (double) buf[y]
                    << endl;
        }
    }
    _TIFFfree(buf);
    TIFFClose(tif);
}

So, my question is is there an straightforward way to extract a particular info for a given pixel, ideally using LibTIFF? If not, what should be the best way to do it? Apologies if the question is very basic, I just could not find any information about it. Thanks in advance.

EDIT: Output of identify -verbose file.tif

  Format: TIFF (Tagged Image File Format)
  Mime type: image/tiff
  Class: DirectClass
  Geometry: 1830x1830+0+0
  Resolution: 1x1
  Print size: 1830x1830
  Units: Undefined
  Colorspace: Gray
  Type: Grayscale
  Endianess: MSB
  Depth: 16/8-bit
  Channel depth:
    Gray: 8-bit
  Channel statistics:
    Pixels: 3348900
    Gray:
      min: 0  (0)
      max: 13107 (0.2)
      mean: 1582.66 (0.0241498)
      standard deviation: 1200.55 (0.0183193)
      kurtosis: 2.79689
      skewness: 1.81966
      entropy: 0.63063
  Colors: 34
 Rendering intent: Undefined
  Gamma: 0.454545
  Matte color: grey74
  Background color: white
  Border color: srgb(223,223,223)
  Transparent color: none
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 1830x1830+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: None
  Orientation: TopLeft
  Properties:
    comment: band2
    date:create: 2018-01-09T21:48:10+00:00
    date:modify: 2018-01-09T21:48:14+00:00
    signature: b3783beb7f7d2bdb32c3c64f8878a02c238a10f221f6a05f93991b26a58a4c78
    tiff:alpha: unspecified
    tiff:endian: msb
    tiff:photometric: min-is-black
    tiff:rows-per-strip: 1830
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 49.3701MiB
  Number pixels: 3348900
  Pixels per second: 3.88504MB
  User time: 0.484u
  Elapsed time: 0:01.861
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
Mantas
  • 33
  • 7
  • Why do you think your TIFF contains doubles? Have you tried `tiffdump yourFile.tif`, or **ImageMagick**'s `identify -verbose yourFile.tif`? – Mark Setchell Dec 28 '17 at 20:50
  • I assumed TIFF contains doubles just because some of the values of a pixel (band value, for instance) are doubles. I am pretty sure I am wrong about it though. No, I have not used tiffdump or ImageMagick. If I understand it right, they would help me to find out the content of a pixel? And then extract whatever is needed? – Mantas Dec 29 '17 at 00:25
  • You just need to run one, or both, and see what you are dealing with. Please click `edit` under your post and paste in the output. – Mark Setchell Dec 29 '17 at 07:20
  • Any news on progress? – Mark Setchell Jan 02 '18 at 17:06
  • Sorry for the late answer @MarkSetchell but no progress has been achieved. I did run `identify -verbose yourFile.tif` but I have no idea how to analyze it. The output file is quite big, so I do not think it is a good idea to paste it here. If you could tell me what information is relevant, that would be great. Thank you. – Mantas Jan 23 '18 at 22:02
  • Just remove the histogram part and post the rest. Posts can be 2MB so you'll be fine. – Mark Setchell Jan 23 '18 at 22:13
  • Maybe you could share the file so folks can try and help further... Dropbox, OneDrive, Google Drive, filebin.net ? – Mark Setchell Jan 23 '18 at 22:37
  • @MarkSetchell I added the output. Sure, I can share the file if that helps. – Mantas Jan 23 '18 at 22:50
  • Yes, please share the file. There's already something strange about it because it has 14.7 bytes per pixel which would still be twice too much if it was RGB and 16-bit pixels. – Mark Setchell Jan 24 '18 at 07:15
  • @MarkSetchell There is the TIFF file. [link](https://www.dropbox.com/s/9icq6crfj865vkg/band2.tif?dl=0) – Mantas Jan 24 '18 at 22:52
  • I just had a quick look and I can read the file fine. It is late here in the UK so I'll work it out properly tomorrow. As a quick guess though, I wouldn't be surprised if your code works if you change `double` to `unsigned short` everywhere. – Mark Setchell Jan 24 '18 at 23:21
  • Well, I can get the values with both `double` or `unsigned short` but the problem is that they do not really make sense. – Mantas Jan 25 '18 at 00:29
  • No problem reading the file and image data (uncompressed big Endian UINT16 stored in one strip). The only "unusual" thing is the tag 65000 containing a ~43 MB DimapDocument string. – cgohlke Jan 28 '18 at 09:16
  • Mmm.. we don't seem to be making much progress here! Maybe you could explain why you think the values are wrong and give examples of what you think they should be and what you actually manage to extract... – Mark Setchell Jan 29 '18 at 14:54
  • @MarkSetchell Sorry, for the late answer, but the problem is solved. There was no problem with the file, the problem was me... :D First of all, this file is RGB which was not what I really needed. I simply needed the values of various bands (both visible and non-visible) and it has nothing to do with RGB format. To achieve this, I had to export file in a slightly different way. Also, I was told that it might be impossible to get what I need from TIFF files. Therefore, I exported it in a different format and processed it successfully. Anyway, I appreciate your help, thanks a lot ;) – Mantas Jan 29 '18 at 21:47

1 Answers1

0

I have had a look at this and am also confused, but maybe if I put what I know as a start of an answer, someone cleverer than me (@fmw42 maybe) can tell us what is going on.

Your image is 16-bit, greyscale. The maximum pixel value in the file is 13,107, which on a scale of 0-65535 equates to 0.2 or 20% meaning all your pixel values only use the low 20% of the available range - i.e. the image is fairly dark. Here is a histogram:

enter image description here

If I look at just the first row of the image with your program (i.e. using libtiff), I see it is black until column 165 - presumably because it is a satellite image and the Earth rotates into the picture as it is scanned.

I can also look at the image using ImageMagick, either the whole image as text:

convert image.tif txt:

Or, just cropping out the first row:

convert image.tif -crop 1830x1+0+0 txt:

When I do that, I also see that the first non-black pixel in the first scanline is at 165, but it, and subsequent pixels, differ from the libtiff values. The libtiff values are on the left in the diagram below and the ImageMagick values are on the right:

enter image description here

I can't see what the difference is - it is not a simple ratio. So I plotted the first scanline of the image as calculated by libtiff (green) and as shown by ImageMagick (purple):

enter image description here

Here I zoom in on the left side - you can see they both start at column 165:

enter image description here

And here I zoom in on the right side:

enter image description here

It looks like one (ImageMagick) has a lower radiometric resolution (fewer bits for the pixel brightness) than the other, because it is more stepped, but sometimes it seems downright lazy and is totally static when it clearly could represent more accurate values.

Here is the output of tiffdump image.tif

image.tif:
Magic: 0x4d4d <big-endian> Version: 0x2a <ClassicTIFF>
Directory 0: offset 10 (0xa) next 0 (0)
ImageWidth (256) LONG (4) 1<1830>
ImageLength (257) LONG (4) 1<1830>
BitsPerSample (258) SHORT (3) 1<16>
Compression (259) SHORT (3) 1<1>
Photometric (262) SHORT (3) 1<1>
ImageDescription (270) ASCII (2) 6<band2\0>
StripOffsets (273) LONG (4) 1<45070554>
SamplesPerPixel (277) SHORT (3) 1<1>
RowsPerStrip (278) LONG (4) 1<1830>
StripByteCounts (279) LONG (4) 1<6697800>
XResolution (282) RATIONAL (5) 1<1>
YResolution (283) RATIONAL (5) 1<1>
PlanarConfig (284) SHORT (3) 1<2>
ResolutionUnit (296) SHORT (3) 1<1>
SampleFormat (339) SHORT (3) 1<1>
34264 (0x85d8) DOUBLE (12) 16<60 0 0 600000 0 -60 0 5.90004e+06 0 0 0 0 0 0 0 1>
34735 (0x87af) SHORT (3) 24<1 1 2 5 1024 0 1 1 1025 0 1 1 1026 34737 22 0 3072 0 1 32629 3073 34737 22 22>
34737 (0x87b1) ASCII (2) 45<WGS 84 / UTM zone 29N|WG ...>
65000 (0xfde8) ASCII (2) 45070067<<?xml version="1.0" enco ...>
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432