fywe
fywe

Reputation: 453

How to recolor grayscale image with fixed colors by ImageMagick using CLUT

I'm pretty new to image processing and ImageMagick, but I couldn't find a straightforward solution to my problem after some searching. I still don't have an understanding how the Color LookUp Table [CLUT] works in ImageMagick.

I have source image:

enter image description here

And I want it look like this:

enter image description here

The idea is that in source image I have gray values which should be converted to color values 1:1

rgb(0, 0, 0)  -> transparent
rgb(1, 1, 1)  -> rgb(253,0,252)
rgb(2, 2, 2)  -> rgb(252,0,23)
rgb(3, 3, 3)  -> rgb(253,125,33)
rgb(4, 4, 4)  -> rgb(254,217,48)
rgb(5, 5, 5)  -> rgb(219, 255, 51)
rgb(6, 6, 6)  -> rgb(59, 255, 46)
rgb(7, 7, 7)  -> rgb(110, 165, 58)
rgb(8, 8, 8)  -> rgb(18, 139, 54)
rgb(9, 9, 9)  -> rgb(44, 255, 254)
rgb(10,10,10) -> rgb(18, 129, 252)
rgb(11,11,11) -> rgb(39, 19, 251)
rgb(12,12,12) -> rgb(115, 115, 115)
rgb(13,13,13) -> rgb(179,179,179)

But I don't know how to create CLUT image in order to make ImageMagick convert it as I want. I tried to create something like this:

enter image description here

... but when I do:

$> convert region_128x128.png color_lookup_table.png -clut region_128x128_clut.png

I'm getting this:

enter image description here

So, the question is, Is it possible to create the CLUT for my problem? If so, could someone please explain it to me?

Update: I found the way to do what I want using ImageMagick, I use this script:

#!/bin/bash

INPUT_FILE=$1
OUTPUT_FILE=$2

convert $INPUT_FILE -fill 'rgba(0,0,0,0.0)' -opaque 'rgb(0, 0, 0)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(253,0,252)' -opaque 'rgb(1, 1, 1)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(252,0,23)' -opaque 'rgb(2, 2, 2)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(253, 125, 33)' -opaque 'rgb(3,3,3)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(254, 217, 48)' -opaque 'rgb(4,4,4)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(219, 255, 51)' -opaque 'rgb(5,5,5)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(59, 255, 46)' -opaque 'rgb(6,6,6)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(110, 165, 58)' -opaque 'rgb(7,7,7)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(18, 139, 54)' -opaque 'rgb(8,8,8)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(44, 255, 254)' -opaque 'rgb(9,9,9)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(18, 129, 252, 1)' -opaque 'rgb(10,10,10,)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(39, 19, 251)' -opaque 'rgb(11,11,11,)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(115, 115, 115)' -opaque 'rgb(12,12,12)' $OUTPUT_FILE
convert $OUTPUT_FILE -fill 'rgb(179,179,179)' -opaque 'rgb(13,13,13)' $OUTPUT_FILE

But this is not optimal solution for sure. Is there any way to make it with CLUT?

Upvotes: 0

Views: 881

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 208003

UGGGGHHH - your solution is very ugly! I can't explain it in the comments, but if you are going to do that sort of thing, be aware of the following:

  • if you use shell variables you MUST quote them else you will always have lots of problems, especially with files with spaces in their names

  • don't run magick many times when once is enough, it will slow things down horribly and also degrade images such as JPEGs

So, sticking as closely as possible to your solution:

#!/bin/bash

INPUT_FILE=$1
OUTPUT_FILE=$2

convert "$INPUT_FILE" \
   -fill 'rgba(0,0,0,0.0)'   -opaque 'rgb(0, 0, 0)' \
   -fill 'rgb(253,0,252)'    -opaque 'rgb(1, 1, 1)' \
   -fill 'rgb(252,0,23)'     -opaque 'rgb(2, 2, 2)' \
   ...
   ...
   -fill 'rgb(253, 125, 33)' -opaque 'rgb(3,3,3)' "$OUTPUT_FILE"

Upvotes: 1

emcconville
emcconville

Reputation: 24439

A couple of techniques I can think of.

Normalization

Stretch the inbound image so the color spectrum will map correctly.

oringal will become new

convert region_128x128.png -normalize color_lookup_table.png -clut region_128x128_clut.png

But this might not be ideal, as you'll not be able to control precisely how that'll affect images.

Pad the look-up table.

Increase the CLUT to cover the full spectrum of colors (even if they are not used).

convert -size 1x255 gradient: -flip  color_lookup_table.png -composite new_color_lookup_table.png

cult

will be come

new clut

convert region_128x128.png new_color_lookup_table.png -clut region_128x128_clut.png

Or just pad with -extent.

convert region_128x128.png \( color_lookup_table.png -extent 1x255 \) -clut region_128x128_clut.png

output

Upvotes: 3

Related Questions