How to tint image to dominant color?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
User avatar
Marsu42
Posts: 75
Joined: 2014-06-12T03:17:45-07:00
Authentication code: 6789
Location: Berlin

How to tint image to dominant color?

Post by Marsu42 »

I'd lke to do something like sepia-tone, but automatically set the tint color to the dominant color of the image (before converting to grey and tint). For example if it's an image of grassland, I'd like to get a grey->green-tint'ed image, if it's sky it should be grey->blue tint.

What I need is...
a) How do I fx(?) to get the dominant color?
b) How to I set this color to -tint?

The actual application is to tint a background image I'm putting under my pictures. In this example, I'd like to tint the (now grey) border to the dominant green color of the image:

Image
Last edited by Marsu42 on 2016-07-02T12:08:35-07:00, edited 1 time in total.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to tint image to dominant color?

Post by snibgo »

It depend on what you mean by "dominant colour". This might be:

Code: Select all

convert scale 1x1! info:
(Adjust as required for your shell.)
A shell script can pull the colour (eg #123ABC) from that, and use it in "-tint".
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to tint image to dominant color?

Post by fmw42 »

Reduce colors to 256 or less. Then get the histogram and get the most frequent color. See -colors and -format "%c" histogram:info: and tinting and duotone

http://www.imagemagick.org/Usage/quantize/#colors
http://www.imagemagick.org/Usage/files/#histogram
http://www.imagemagick.org/Usage/color_mods/#tinting
http://www.imagemagick.org/Usage/color_mods/#duotone

What is your IM version and platform. Please always provide that information.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to tint image to dominant color?

Post by fmw42 »

Perhaps you might want to just use the dominant hue and set some desired lightness and saturation. If so, then extract the hue channel, reduce colors as desired and then look at the histogram of the modified hue channel for the dominant (most frequent) hue.
User avatar
Marsu42
Posts: 75
Joined: 2014-06-12T03:17:45-07:00
Authentication code: 6789
Location: Berlin

Re: How to tint image to dominant color?

Post by Marsu42 »

fmw42 wrote:What is your IM version and platform. Please always provide that information.
Sorry, I'm running Windows x64 with im7 q16 hdri
snibgo wrote:It depend on what you mean by "dominant colour". This might be:

Code: Select all

convert scale 1x1! info:
(Adjust as required for your shell.)
A shell script can pull the colour (eg #123ABC) from that, and use it in "-tint".
Um, is there a im7 (yay! I'm up to date :-)) version of this? What I'm getting is...

Code: Select all

magick.exe image.jpg -scale 1x1! info:
image.jpg JPEG 1x1 1x1+0+0 8-bit sRGB 0.641u 0:00.650
fmw42 wrote:Perhaps you might want to just use the dominant hue and set some desired lightness and saturation. If so, then extract the hue channel, reduce colors as desired and then look at the histogram of the modified hue channel for the dominant (most frequent) hue.
Ugh, that'll require some reading for me, but I'll try to manage to find the correct commands and then hope that it'll do what I want it to do :-p
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to tint image to dominant color?

Post by fmw42 »

Code: Select all

magick.exe image.jpg -scale 1x1! -format "%[pixel:u.p{0,0}]" info:
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to tint image to dominant color?

Post by fmw42 »

You could also crop the image into some number of equally sized subsections and do the above on that for each subsection and then find the most frequent color from all the subsections. You might have to look for close colors within some fuzz value via scripting your OS.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to tint image to dominant color?

Post by snibgo »

Sorry, I didn't mean "info:" but "txt:". Or, as Fred says, "info:" with a format.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to tint image to dominant color?

Post by fmw42 »

snibgo wrote:Sorry, I didn't mean "info:" but "txt:". Or, as Fred says, "info:" with a format.

He means:

Code: Select all

magick.exe image.jpg -scale 1x1! txt:
which provides more information about the color that would have to be parsed
User avatar
GeeMack
Posts: 718
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: How to tint image to dominant color?

Post by GeeMack »

Marsu42 wrote:I'd lke to do something like sepia-tone, but automatically set the tint color to the dominant color of the image...
Using "ImageMagick 7.0.2-2 Q16 x64" on Windows 7 64, this command might have most of what you need to get the job done...

Code: Select all

magick "input.jpg" ^
   ( ^
      +clone ^
      -resize 1x1! ^
      -set option:pcolor "%[fx:p.r*255],%[fx:p.g*255],%[fx:p.b*255]" ^
      +delete ^
   ) ^
   -colorspace gray ^
   ( ^
      -size 8x256 ^
      gradient:white-black ^
      -fill "rgb(%[pcolor])" ^
      -tint 100% ^
      -rotate 90 ^
   ) ^
   -clut ^
      "output.jpg"
It starts by bringing in your source image.

Inside the first set of parentheses it clones the input image.

Then it resizes that clone to a single pixel averaging all the colors into one.

Next it sets an IM variable to contain the R, G, and B values of the color of that one pixel.

Then it deletes that 1x1 temporary image.

After the first parenthesis it turns the input image to grayscale.

Inside the second set of parentheses it makes an 8x256 white-black gradient image.

Then it sets the fill color to that variable we made from the 1x1 color pixel above.

Using that fill color it tints the 8x256 gradient strip.

Before exiting that set of parenthesis it has to rotate the 8x256 image 90 degrees so we can use it as a color lookup table (-clut) in the next step.

Outside the parentheses it uses the "-clut" operator to apply the color gradient from that 256x8 image to the grayscale version of your input image.

Finally it names the output file and voila, done!

You can tweak the command by increasing or decreasing the percentage of the "-tint 100%" operator. I liked the result better at 110%. You may want to adjust the levels or normalize the image after you turn it to grayscale or before the final output. Of course you can add some "-modulate" or other color modifiers along the way to adjust the saturation, brightness, or contrast.

If you use this in a .bat file you'll need to make all the single percent signs "%" into doubles "%%".
User avatar
Marsu42
Posts: 75
Joined: 2014-06-12T03:17:45-07:00
Authentication code: 6789
Location: Berlin

Re: How to tint image to dominant color?

Post by Marsu42 »

GeeMack wrote: Inside the second set of parentheses it makes an 8x256 white-black gradient image.
Then it sets the fill color to that variable we made from the 1x1 color pixel above.
Using that fill color it tints the 8x256 gradient strip.
Before exiting that set of parenthesis it has to rotate the 8x256 image 90 degrees so we can use it as a color lookup table (-clut) in the next step.
Outside the parentheses it uses the "-clut" operator to apply the color gradient from that 256x8 image to the grayscale version of your input image.
Thanks, the in-im calculation is certainly fancy, though atm I need the rgb values in the shell to compute the color intensity and dim it down with modulate if necessary ... I'll ask around if that can be done inside im in another thread if necessary.

What I don't understand about your version is the whole color lookup table part - with my limited testing right now, it gives exactly the same result as as the simple "-fill "rgb()" -tint" version from above? It might be more flexible though if you modify the color lookup before applying though?
fmw42 wrote:You could also crop the image into some number of equally sized subsections and do the above on that for each subsection and then find the most frequent color from all the subsections. You might have to look for close colors within some fuzz value via scripting your OS.
fmw42 wrote:Perhaps you might want to just use the dominant hue and set some desired lightness and saturation. If so, then extract the hue channel, reduce colors as desired and then look at the histogram of the modified hue channel for the dominant (most frequent) hue.
These two options sound interesting, I'll try them sooner or later and report back if I need further help :-o. The problem with the simple -resize 1x1! averaging approach is that for example a sky & grass picture always results in a brownish tint - better than the dull gray before, but the "dominant color" approach might look better still.
User avatar
GeeMack
Posts: 718
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: How to tint image to dominant color?

Post by GeeMack »

Marsu42 wrote:What I don't understand about your version is the whole color lookup table part - with my limited testing right now, it gives exactly the same result as as the simple "-fill "rgb()" -tint" version from above? It might be more flexible though if you modify the color lookup before applying though?
Yep. It's just a way to manipulate it in isolation. I have a couple tinting scripts that stretch the center of the table and do some level adjusting before applying it to the grayscale image. Sometimes I'll do "-write testclut.png" inside the parentheses so I can look at the table to see what it's doing. It's mostly just what I'm familiar with.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to tint image to dominant color?

Post by fmw42 »

If on Unix (Linux, Mac OSX or Windows with Cygwin), you can use my kmeans script to get the dominant color. (Note this will depend upon the seed colors or the number of seed colors you specify).

I cropped your image to remove your original border.
Image

Then did the following. (Note the resize is simply to make the kmeans iteration process run faster).

Code: Select all

convert axel-luessow_crop.png -resize 50x50 tmp.png

dominantcolor=`kmeans_tmp -n 6 -C sRGB -m 5 -v dominant tmp.png null:`
echo "$dominantcolor"
#939571FF

convert axel-luessow_crop.png -bordercolor "$dominantcolor" -border 100 axel-luessow_crop_pad100.png
Image
Post Reply