[GRASS5] r.in.gdal and colors

Hi,

I'm working on an introductory text for newbies. In that context I've been
playing around with r.in.gdal on simple raster files. However, I have
trouble getting the "right" colors.

I'm using the image at
http://earthobservatory.nasa.gov/Newsroom/NewImages/Images/PIA03346.jpg,
and import it with r.in.gdal which gives me 3 maps. However, they all are
in different colors than the original image. Is there a quick way to
recreate these colors, or does it have to be done "by hand".

Moritz

Moritz Lennert writes:
> http://earthobservatory.nasa.gov/Newsroom/NewImages/Images/PIA03346.jpg,
> and import it with r.in.gdal which gives me 3 maps. However, they all are
> in different colors than the original image. Is there a quick way to
> recreate these colors, or does it have to be done "by hand".

Have you tried this advice from Glynn?

> the colour tables with e.g "r.colors img.1 color=grey". You can
> display the layers with e.g. "d.rgb r=img.1 g=img.2 b=img.3".

The thing I'd like to know is how to get them back into one map again.

--
-russ nelson http://russnelson.com | You get prosperity when
Crynwr sells support for free software | PGPok | the government does less,
521 Pleasant Valley Rd. | +1 315 268 1925 voice | not when the government
Potsdam, NY 13676-3213 | +1 315 268 9201 FAX | does something right.

Moritz Lennert writes:
> http://earthobservatory.nasa.gov/Newsroom/NewImages/Images/PIA03346.jpg,
> and import it with r.in.gdal which gives me 3 maps. However, they all
are
> in different colors than the original image. Is there a quick way to
> recreate these colors, or does it have to be done "by hand".

Have you tried this advice from Glynn?

> the colour tables with e.g "r.colors img.1 color=grey". You can
> display the layers with e.g. "d.rgb r=img.1 g=img.2 b=img.3".

Thanks that did it. Don't understand why I have to go through grey to get
colors, but oh well...

The thing I'd like to know is how to get them back into one map again.

r.composite

Moritz

Moritz Lennert writes:
> Thanks that did it. Don't understand why I have to go through grey to get
> colors, but oh well...

Makes no sense to me either. If r.in.gdal splits an image up into R,
G, and B, then it ought to set the colormap for those rasters to
grey. When would you ever want it otherwise??

> r.composite

Thanks!

--
-russ nelson http://russnelson.com | You get prosperity when
Crynwr sells support for free software | PGPok | the government does less,
521 Pleasant Valley Rd. | +1 315 268 1925 voice | not when the government
Potsdam, NY 13676-3213 | +1 315 268 9201 FAX | does something right.

Russell Nelson wrote:

> Thanks that did it. Don't understand why I have to go through grey to get
> colors, but oh well...

The code needs a way to translate category values to intensities. It
does this by using the intensities from the map's colour table. If the
colour table is wrong, everything which tries to use it will produce
the wrong result.

Makes no sense to me either. If r.in.gdal splits an image up into R,
G, and B, then it ought to set the colormap for those rasters to
grey. When would you ever want it otherwise??

AFAICT, the problem is that r.in.gdal (maybe others) don't set *any*
colour table, so you get the default colour table ("rainbow").

For importing most image formats, I suggest converting to PPM (e.g.
via "djpeg"), then using "r.in.ppm -b" (r.in.ppm *does* set the colour
table correctly).

The main exceptions are PNG (r.in.png will preserve some information
which could be lost by going via PPM) and TIFF (r.in.tiff and
r.in.gdal can extract geographic data from .tfw files or GeoTIFF
images respectively).

However, the problem with using "r.colors ... color=grey" is that it
will map black and white to the lowest and highest categories which
are actually used, rather than to the logical range of the data.

A better approach is to use color=rules, and explicitly map
black/white to 0/255 (or 0.0/1.0 for FP), e.g.

  r.colors map=... color=rules
  0 black
  255 white
  end

> > The thing I'd like to know is how to get them back into one map again.
>
> r.composite

Thanks!

First, you should be asking yourself whether you want to get them back
into one map again. For most purposes (considering that GRASS is an
analysis package, not a paint program), it's best to leave them as
three separate maps, where the cell values are meaningful.

If you generate a composite map with r.composite, the resulting
categories are basically meaningless; about the *only* thing you can
actually do with the image is to display it. Furthermore, unless you
use "r.composite ... levels=256" (which is slow in itself, and also
makes some other operations slow), a composite map will usually have
lower colour resolution than separate bands.

To date, I've only discovered one scenario which requires the use of a
composite map, and that is for use as a colour layer in NVIZ. The
other common operations upon a composite map all have equivalents
which operate upon separate R/G/B layers:

  Composite Separate Bands

  d.rast d.rgb
  r.out.ppm r.out.ppm3
  r.in.ppm -c r.in.ppm -b
  ps.map/raster ps.map/rgb

--
Glynn Clements <glynn.clements@virgin.net>

On Wed, Feb 05, 2003 at 10:53:17AM -0500, Russell Nelson wrote:

Moritz Lennert writes:
> Thanks that did it. Don't understand why I have to go through grey to get
> colors, but oh well...

Makes no sense to me either. If r.in.gdal splits an image up into R,
G, and B, then it ought to set the colormap for those rasters to
grey. When would you ever want it otherwise??

AFAICT, r.in.gdal only writes a color map if the image source has a
color map. This is not usually the case for RGB type images.
The default color map in GRASS is a rainbow...

--
echo ">gra.fcw@2ztr< eryyvZ .T pveR" | rot13 | reverse

Eric G. Miller wrote:

On Wed, Feb 05, 2003 at 10:53:17AM -0500, Russell Nelson wrote:

Moritz Lennert writes:
> Thanks that did it. Don't understand why I have to go through grey to get
> colors, but oh well...

Makes no sense to me either. If r.in.gdal splits an image up into R,
G, and B, then it ought to set the colormap for those rasters to
grey. When would you ever want it otherwise??

AFAICT, r.in.gdal only writes a color map if the image source has a
color map. This is not usually the case for RGB type images.
The default color map in GRASS is a rainbow...

Eric / Russell,

Do you or others who get the Zen of GRASS better than I think r.in.gdal ought
to be writing a greyscale colortable for imported files without a colormap?
Should it only do this for multiband images? Only for 8bit images?

I would be happy to make changes, but I don't want to imply color tables where
they don't exist unless it is widely accepted as the correct thing to do.

Best regards,

--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up | Frank Warmerdam, warmerdam@pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush | Geospatial Programmer for Rent

On Wed, Feb 05, 2003 at 10:30:51PM -0500, Frank Warmerdam wrote:

Eric / Russell,

Do you or others who get the Zen of GRASS better than I think
r.in.gdal ought to be writing a greyscale colortable for imported
files without a colormap? Should it only do this for multiband
images? Only for 8bit images?

I would be happy to make changes, but I don't want to imply color
tables where they don't exist unless it is widely accepted as the
correct thing to do.

Zen of GRASS? I dunno, I think maybe GRASS should be changed to
assume min/max linear greyscale when no color table exists...
I vaguely recall some discussion about this the last time it
came up, but I don't recall if there was a resolution to change
GRASS.

Of course, min/max per band isn't really correct for RGB imagery
since it can skew the colors, but we can't assume 0-255 with 32-bit
ints. The imagery groups can specify RGB bands, but that doesn't
come into play for d.rgb (i.composite uses the settings, but a
colortable of 256*256*256 is unwieldy). I don't know if there's a
perfect solution. Using imagery groups is probably the correct route,
since the colortable semantics can be bypassed with a proper display
program (say, the unwritten d.image ...).

--
echo ">gra.fcw@2ztr< eryyvZ .T pveR" | rot13 | reverse

Frank Warmerdam writes:
> Do you or others who get the Zen of GRASS better than I think
> r.in.gdal ought to be writing a greyscale colortable for imported
> files without a colormap?

Yes. The three rasters are not independent images, but are instead
the red, green, and blue planes of the imported image. For that
reason, they should have greyscale colortables, and should be named
".r", ".g", and ".b" instead of .1, .2, and .3.

> Should it only do this for multiband
> images? Only for 8bit images?

If it's an indexed image and comes with a colortable, then by all
means set the colortable. Otherwise, if it's an RGB image, then the
resultant three rasters should be interpreted not as colors, but as
intensities. And that means greyscale.

--
-russ nelson http://russnelson.com | You get prosperity when
Crynwr sells support for free software | PGPok | the government does less,
521 Pleasant Valley Rd. | +1 315 268 1925 voice | not when the government
Potsdam, NY 13676-3213 | +1 315 268 9201 FAX | does something right.

Eric G. Miller writes:
> Of course, min/max per band isn't really correct for RGB imagery
> since it can skew the colors, but we can't assume 0-255 with 32-bit
> ints.

If r.in.gdal is reading an image with 24 bits per pixel (e.g. a jpg),
and it writes those 24 bits into three 8-bit-deep rasters, then it
seems to me that a greyscale colortable of 0-255 is the ONLY right
thing to do.

--
-russ nelson http://russnelson.com | You get prosperity when
Crynwr sells support for free software | PGPok | the government does less,
521 Pleasant Valley Rd. | +1 315 268 1925 voice | not when the government
Potsdam, NY 13676-3213 | +1 315 268 9201 FAX | does something right.

On Wed, Feb 05, 2003 at 11:43:59PM -0500, Russell Nelson wrote:

Eric G. Miller writes:
> Of course, min/max per band isn't really correct for RGB imagery
> since it can skew the colors, but we can't assume 0-255 with 32-bit
> ints.

If r.in.gdal is reading an image with 24 bits per pixel (e.g. a jpg),
and it writes those 24 bits into three 8-bit-deep rasters, then it
seems to me that a greyscale colortable of 0-255 is the ONLY right
thing to do.

GRASS has one integer CELL type (32 bits wide). However, I think it's
probably true that r.in.gdal could be improved.

(1) Use G_set_cell_format() before writing out each band. This sets the
    max bytes which is used to save space (1..sizeof(CELL)). From the
    looks of it, this could be pretty straight forward from GDAL (though
    I don't know the GDAL API).

(2) Write grey scale color rules for each band:
    (a) If 8 bits / band, write 0-255 grey scale color rule. [1]
    (b) If > 8 bits / band, write min/max grey scale color rule?

(3) Set RED/GREEN/BLUE imagery interpretation if/when known for
    imagery groups.

    Apparently, there's no API to set the colors programatically?
    But, libes/imagery/ask_colors.c has:

   /**************************************************************
    * step 5 - finish
    * set the colors
    */
       ref->red.n = r;
       ref->grn.n = g;
       ref->blu.n = b;

    Where "r", "g", and "b" are the integer indices for the respective
    bands of the imagery group...

[1] r.in.tiff does this, but it is much less flexible than r.in.gdal for
    image formats and doesn't even mess with the imagery stuff.

--
echo ">gra.fcw@2ztr< eryyvZ .T pveR" | rot13 | reverse

Frank Warmerdam wrote:

> AFAICT, r.in.gdal only writes a color map if the image source has a
> color map. This is not usually the case for RGB type images.
> The default color map in GRASS is a rainbow...

Eric / Russell,

Do you or others who get the Zen of GRASS better than I think r.in.gdal ought
to be writing a greyscale colortable for imported files without a colormap?
Should it only do this for multiband images? Only for 8bit images?

For RGB "image" files, it should be writing a greyscale colour table.
Otherwise, there's no way for e.g. d.rgb to reliably determine the
interpretation of the cell values; d.rgb (et al) shouldn't just assume
a 0-255 range.

E.g. r.in.png preserves the original bit depth; it doesn't coerce the
data to 8 bits. So, if the data is 4-bpp, the output map will use
categories 0-15, with a colour table which maps 0 to black and 15 to
white. Also, if the sBIT tag is present, it will use that information;
e.g. if the data is stored as 4-bpp, but the sBIT record says that it
was promoted from 3-bpp, then the resulting map will use categories
0-7.

FWIW, both "r.in.ppm -b" and r.in.png write greyscale colour tables.

For JPEG data, there would ideally be an option to output the raw
Y/Cr/Cb channels at their individual resolutions (the Y channel
typically has twice the spatial resolution in each direction), rather
than converting to R/G/B. Similarly for any other colour spaces which
might plausibly be used (the libjpeg documentation indicates that it
supports CMYK and YCCK directly, and supports "pass-through" of other
spaces).

Other issues include gamma correction (i.e. whether this should be
performed by modifying the actual cell values or the colour table),
and images with more than 8 bits-per-pixel (cell values aren't
restricted to 0-255, but colour table entries are).

--
Glynn Clements <glynn.clements@virgin.net>

On Wed, Feb 05, 2003 at 11:20:46PM -0500, Russell Nelson wrote:

Frank Warmerdam writes:
> Do you or others who get the Zen of GRASS better than I think
> r.in.gdal ought to be writing a greyscale colortable for imported
> files without a colormap?

Yes. The three rasters are not independent images, but are instead
the red, green, and blue planes of the imported image. For that
reason, they should have greyscale colortables, and should be named
".r", ".g", and ".b" instead of .1, .2, and .3.

Also I vote for this suggestion.

> Should it only do this for multiband
> images? Only for 8bit images?

If it's an indexed image and comes with a colortable, then by all
means set the colortable. Otherwise, if it's an RGB image, then the
resultant three rasters should be interpreted not as colors, but as
intensities. And that means greyscale.

Right.

Markus