1

In my "wildest dreams," I would like to pass an image to a method like so (pseudoC#):

string pathToOriginalImg = @"http://commons.wikimedia.org/wiki/File:Mark_Twain_by_AF_Bradley.jpg";
Image colorizedImg = new ColorizeImage(pathToOriginalImg, [array of colors]);

IOW, pass the path of an image to be colorized to a method, along with an array of colors you want to be used in the colorization. For example, if I wanted to "Spanishize" this image of Mark Twain, I might want to pass it the colors of the flags of Spain and Mexico, something like: Forest Green, White, MexicanRed; SpanishRed, Yellow.

Is this possible, or am I one log short of a cabin in even wishing for such?

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 1
    You can easily change the color of each single pixel of an image. A completely different story is that these changes would "make sense" to you, that is: the final image would look exactly as you want. See a picture as a bunch of consecutive squares (millions of them): performing more or less complex/synchronised modifications can become a very difficult task. – varocarbas Feb 28 '14 at 17:00
  • Um - before / after example? – Dave Bish Feb 28 '14 at 17:03
  • 1
    hmm, interesting, I suppose you could use a standard 'posterize' function to convert the image to however many colours and then another function to swap out each of those colours with your target ones. No idea if it would look good though... – Starscream1984 Feb 28 '14 at 17:04
  • 2
    What about a function for teaching a picture of mark twain the spanish language? If that is useful, try this: `Image TeachSpanish(Image img) { return img; }` ...don't ask me how it works, it just does – musefan Feb 28 '14 at 17:05
  • 1
    I suspect that you could always use a dithering algorithm with a predetermined set of colors. The results won't be pretty, but it's a start. For a very crude version, iterate over the pixels in the image and compare their distance (you can use the usual formula of `sqrt(r^2 + g^2 + b^2)`) to each of the colors. Substitute the color that's closest to the original pixel. More sophisticate algorithms could use dithering to mix the colors to create more of a gradient effect. – Sean Duggan Feb 28 '14 at 17:17
  • @DaveBish: Since I don't know how to do it, you'll have to use your imagination. Maybe the method would determine the most "colorizable"area, and use the first color on that (etc.) – B. Clay Shannon-B. Crow Raven Feb 28 '14 at 17:18
  • @musefan: I know you were joshing, but actually, something like that might work, too: a "bubble" with one of his famous sayings in Spanish could also get the idea across. – B. Clay Shannon-B. Crow Raven Feb 28 '14 at 17:20

4 Answers4

3

Your description resembles pseudocoloring, where you map source colors to new colors based on a mapping pattern. Of course, how you will map completely depends on you and automating it for every image in a way that it makes sense (somehow) is almost impossible at best. You could define some general rules, however, such as always try to map green to one of these if they are available: yellow, then blue, then grayscale 58%. Reading here may give you additional ideas. As an example pattern for 256 color RGB images as source and 6 color for target image, you may divide 256 by 6, and for every "color region", you provide a new color from your target color array. The resultant image would have only 6 colors, and details would almost certainly be lost.

mcy
  • 1,209
  • 6
  • 25
  • 37
2

It is possible but quite complicated...

First of all you need to translate the colors of your image into another color space. the RGB one doesn't hold the characteristics of human perception of colors if I might say. So if you want a good looking result, you'll need to use another one (like HSL).

See here for the different color spaces: http://en.wikipedia.org/wiki/Color_space

With HSL you could "move" some colors to another value, but keeping the luminosity and saturation parameters.

The biggest problem here is to know when to move a color an when to keep it in place, and I think the results might look odd with first attempts.

Also you might need to run some kind of color analysis before deciding which pixels in the image should have their hue component modified. For example you could use a canny edge detection algorithm to detect portions of the image where the colors are quite uniform, and use interpolation instead of color replacing on the edges detected. That's just an idea there may be a lot of other ways.

This is a broad explanation of how you could achieve this.

I think this link could give you some useful information about color manipulation in an image, this could be a start: How to harmonize a color image

Also a google search about Color harmonization could give you some clues.

I've tried something like this some time ago, if I have some time I'll dig it up and can post the code used. There are some useful tools for color space conversion and such things in my code, it isn't optimized at all, but it's helpful when you're trying to figure out how to proceed.

Community
  • 1
  • 1
ppetrov
  • 3,077
  • 2
  • 15
  • 27
2

If your image uses indexed colors and a Color Lookup Table (LUT) then you'd only need to change the LUT to get every pixel that uses that index to change.

Your image probably doesn't use a LUT, but you can use a utility to make it use one. Something like ImageMagick (use the "-colors" command) can do color reduction, and then write a palletized image. Use the LUT from a different image on the first, and you've got your color change (use the ImageMagick "-clut" command to do this).

Dithermaster
  • 6,223
  • 1
  • 12
  • 20
1

The Answer on this post may help you, its for creating an overlay over an image, that overlay could be your flag or whatever you want

Community
  • 1
  • 1
Shredder2500
  • 1,065
  • 2
  • 11
  • 26