2
votes

I want to use ImageMagick to change colour in shade.

I am able to manage the shade change using :

convert input.png  -colorspace HCL -channel R  -evaluate set 5%  +channel -colorspace sRGB output.png 

Using set XX% i am able to get different colours like, red, green, yellow, blue, pink, sky-blue, gray, etc.

The below command works for targeting blue colour :

convert input.png  -colorspace HCL -channel R -separate +channel -level 48,52% output.png 

But I am unable to target other colour explicitly.

For example, if I want to change green colour with some other colour, resulted image will effect green, yellow,red and sky-blue as well.

Is there a way to explicitly change a single colour in shade for :

  • yellow
  • sky-blue
  • pink
  • green
  • white
  • black
  • red

I tried changing all -channel : R,G,B,C,M,Y,K,A,O.

Using -separate option I can target RBG, but the problem with RGB is R effect red, yellow and pink, G effect green, sky-blue and yellow and B effect blue, pink and Sky-blue.

sample for output : RGB image colour change

expected output : In the above output for "output-0" it effect red,yellow and pink. i want the command which will effect only red. similarly for other colours as well.

links I used : https://www.imagemagick.org/discourse-server/viewtopic.php?t=33361

I am using python to run this command. I am also open to use other libraries which will work with all the colours explicitly.

1
Please provide a sample image representative of the ones you are using and also show what sort of result you expect.Mark Setchell
I have a bash Imagemagick script that will change individual colors. See my script, huemap, at fmwconcepts.com/imagemagick/index.html. This is a hue rotation effect. Black and white are not hues, so you won't be able to change those. For that use -fuzz XX% -fill skyblue -opaque white to change white to skyblue. You can also do that for any color as per Mark Setchell's answer.fmw42
Did my answer sort out your problem? If so, please consider accepting it as your answer - by clicking the hollow tick/checkmark beside the vote count. If not, please say what didn't work so that I, or someone else, can assist you further. Thanks. meta.stackexchange.com/questions/5234/…Mark Setchell

1 Answers

1
votes

If your image is representative like I requested, it is as simple as this:

enter image description here

magick rgb.png -fill white -opaque red result.png

enter image description here

If you also want to affect hues "close to red", you can apply some fuzz:

magick rgb.png -fuzz 40% -fill white -opaque red result.png

enter image description here

Notice that also affects the edges of the red circle where it is a "feathered red".


If not, your ImageMagick code is essentially doing a "Hue rotation" and, as you have noticed, it affects the entire image. Read the Wikipedia page on HSV before continuing. Here is an HSI Hue wheel for reference:

enter image description here

The solution is to do your Hue rotation, but apply its effects via a mask that only selects the colours/areas you want affected. Remember that OpenCV halves the Hue from the range 0..360 to 0..180 so that it can store a Hue in a np.uint8.

So, if we load the same image as above and select only the greens (where Hue is near 120) we can rotate just those into blues by adding 60 (Hue=240):

#!/usr/local/bin/python3
import cv2 as cv
import numpy as np

# Load the image and convert to HSV colourspace
image = cv.imread("rgb.png")

# Convert to HSV and split channels
hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
H,S,V = cv.split(hsv)

# Shift only greens (Hue near 120) around hue circle by 120 degrees to blues - remembering OpenCV halves all these values - see comment
H[(H>55)&(H<65)] += 60

# Recombine into single 3-channel image and convert back to RGB
result = cv.merge((H,S,V))
result = cv.cvtColor(result,cv.COLOR_HSV2BGR)

cv.imwrite("result.png",result)

enter image description here


If you want to change the blues (Hue=240) into yellows (Hue=60), just change this:

H[(H>55)&(H<65)] += 60

into this:

H[(H>115)&(H<125)] -= 90

enter image description here


If you want to broaden the range of greens affected, decrease the 55 in my code and/or increase the 65. If you want to move greens to a different hue, either increase or decrease the 60.

You can do all the stuff above with PIL/Pillow if you want to - you don't need to install the (massive) OpenCV.

Keywords: Image, image processing, Python, OpenCV, ImageMagick, Hue, HSL, HSV, hue rotation, colour replacement, selective colour, mask.