1

I have more then 1 week reading about selective color change of an image. It meand selcting a color from a color picker and then select a part of image in which I want to change the color and apply the changing of color form original color to color of color picker.

E.g. if I select a blue color in color picker and I also select a red part in the image I should be able to change red color to blue color in all the image.

Another example. If I have an image with red apples and oranges and if I select an apple on the image and a blue color in the color picket, then all apples should be changing the color from red to blue.

I have some ideas but of course I need something more concrete on how to do this

Thank you for reading

Drill
  • 169
  • 2
  • 3
  • 12
  • Except for wanting to apply it only to certain areas, how similiar is what you want to do to http://stackoverflow.com/questions/7274221/changing-image-hue-with-python-pil (if you don't mind python) This is about changing hue w/o changing brightness. – DarenW Nov 11 '12 at 01:31
  • Identical to http://stackoverflow.com/q/7171679/10468 except that one is iPhone-specific. – DarenW Nov 11 '12 at 01:33
  • What are your ideas ? This is not really trivial, it is going to require proper color clustering. The color space used might help too. – mmgp Jan 12 '13 at 22:59

2 Answers2

1

As a starting point, consider clustering the colors of your image. If you don't know how many clusters you want, then you will need methods to determine whether to merge or not two given clusters. For the moment, let us suppose that we know that number. For example, given the following image at left, I mapped its colors to 3 clusters, which have the mean colors as shown in the middle, and representing each cluster by its mean color gives the figure at right.

enter image description here enter image description here enter image description here

With the output at right, now what you need is a method to replace colors. Suppose the user clicks (a single point) somewhere in your image, then you know the positions in the original image that you will need to modify. For the next image, the user (me) clicked on a point that is contained by the "orange" cluster. Then he clicked on some blue hue. From that, you make a mask representing the points in the "orange" cluster and play with that. I considered a simple gaussian filter followed by a flat dilation 3x5. Then you replace the hues in the original image according to the produced mask (after the low pass filtering, the values on it are also considered as a alpha value for compositing the images).

enter image description here

Not perfect at all, but you could have a better clustering than me and also a much-less-primitive color replacement method. I intentionally skipped the details about clustering method, color space, and others, because I used only basic k-means on RGB without any pre-processing of the input. So you can consider the results above as a baseline for anything else you can do.

mmgp
  • 18,901
  • 3
  • 53
  • 80
0

Given the image, a selected color, and a target new color - you can't do much that isn't ugly. You also need a range, some amount of variation in color, so you can say one pixel's color is "close enough" while another is clearly "different".

First step of processing: You create a mask image, which is grayscale and varying from 0.0 to 1.0 (or from zero to some maximum value we'll treat as 1.0), and the same size as the input image. For each input pixel, test if its color is sufficiently near the selected color. If it's "the same" or "close enough" put 1.0 in the mask. If it's different, put 0.0. If is sorta borderline, put an in-between value. Exactly how to do this depends on the details of the image.

This might work best in LAB space, and testing for sameness according to the angle of the A,B coordinates relative to their origin.

Once you have the mask, put it aside. Now color-transform the whole image. This might be best done in HSV space. Don't touch the V channel. Add a constant to S, modulo 360deg (or mod 256, if S is stored as bytes) and multiply S by a constant chosen so that the coordinates in HSV corresponding to the selected color is moved to the HSV coordinates for the target color. Convert the transformed S and H, with the unchanged L, back to RGB.

Finally, use the mask to blend the original image with the color-transformed one. Apply this to each channel - red, green, blue:

output = (1-mask)*original + mask*transformed

If you're doing it all in byte arrays, 0 is 0.0 and 255 is 1.0, and be careful of overflow and signed/unsigned problems.

DarenW
  • 16,549
  • 7
  • 63
  • 102
  • Thank you indeed for your answer. Well you`re right about tha range. What about using min and max values of HUE of selected color(selected part of the image) and then use [min, max] as range. Everything that is in this range will be 1.0, if it is different it will be 0.0. I didn`t understand the "in between value". How can I know what value to put in this case? – Drill Nov 11 '12 at 12:45
  • I also have some uncleared things to this part "and multiply S by a constant chosen so that the coordinates in HSV corresponding to the selected color is moved to the HSV coordinates for the target color". This constant should be calculated for every pixel right, in order to move values from "old S" to the "new S" that corresponds to HSV of target color? – Drill Nov 11 '12 at 12:45
  • one another thing. S is between 0 and 1 in C# – Drill Nov 11 '12 at 12:50
  • You can select color by H, S, V, R, G, B, L, A, B or any mathematical combination. You can have a range - a color is "in" if it's between some min and max threshold values. Or you can define a maximum absolute difference from some specific value. I described a basic, simple example but I've had to concoct some very messy color-matching masks in my career. – DarenW Nov 14 '12 at 08:25
  • The "in between values" means you shouldn't have a hard distinction between 0 for colors outside some range and 1.0 inside. You're likely to get ugly edges around objects and only parts of smooth objects affected where the light is nonuniform (which is practically everywhere) – DarenW Nov 14 '12 at 08:28