Additive blending of RGB colors representing light - algorithm

I have a RGB color that represents light. I am looking for an algorithm to draw this over an arbitrary background (could be, for example, an image) in a way that simulates (or resembles) lighting.
Some examples:
RGB=#888888 represents white light at 50% intensity
Painting this over white (#ffffff) background pixels would do nothing
Painting this over black (#000000) background pixels would paint as #888888
Painting this over red (#ff0000) background pixels would result in a "lighter red"
RGB=#ff0000 represents red light at 100% intensity
Painting this over white (#ffffff) background pixels should result in a "light red" (mix of red and white)
Painting this over black (#000000) background pixels would paint as #880000
RGB=#000000 represents no light. Painting this over any background should have no effect.
I was hoping that I would be able to translate the original RGB color in (a set of) RGBA color(s) that I could paint over the background. I have been looking for an algorithm for this and playing around with HSL, HSB, alpha, etc. but cannot find a generic way to accomplish this.
Is there a generic algorithm to achieve what I want?
Update: I am aware of this question, but I don't think this is a duplicate (despite the similar names). The accepted answer to that question describes a behaviour (Red + Black = Dark red) that does not match this sceneario (lighting). I am specifically looking for an algorithm to simulate (colored) lighting.

If you view the values as decimal you have values that range 0-255. You could sum the two colours and then rescale them back to the range.
FF0000 + FFFFFF
= 255,0,0 + 255,255,255
= 510,255,255
Then scale this by 255/510 to
510 * 255/510, 255 * 255/510, 255 * 255/510
= 255, 127, 127
A light red as required.

Related

How to include alpha channel to calculate color difference with Spatial CIELAB (S-CIELAB)?

Of course I know how to convert RGB to LAB and LAB to RGB, color difference calculation is mentioned at https://en.wikipedia.org/wiki/Color_difference.
However, it does not mention anything about opacity.
I would like to know how to convert RGBA to LAB with semi-transparent, just including the opacity into the CIELAB ΔE* formula.
Original image
Image converted to 256 colors with formula abs(R1 - R2) + abs(G1 - G2) + abs(B1 - B2) + abs(alpha1 - alpha2) as fitting function to select palette and dithering
Image converted to 256 colors with formula abs(L1 - L2) + abs(a1 - a2) + abs(b1 - b2) + abs(alpha1 - alpha2) as fitting function to select palette and dithering
Composite the possibly-transparent image with a black background, then work with color differences.
As CIELAB is a 3 dimensional color space, the formula should be square(CIE76) + square(alpha1 - alpha2) / exp(1.5) as fitting function to select palette. Then using RGBA color space to perform dithering.
More importantly, the alpha threshold should set to 15 to filter out the nearly transparent pixels.
"For dithering, even though it is the human visual system that is blending the colors of the adjacent pixels, we don’t just want a color space that models the perception of human eye – we want a color space that models the device!
Consider a yellow pixel above a blue pixel. The yellow pixel has the red and green elements fully lit, while the blue pixel has only the blue element. On the other hand, the midpoint between pure yellow and blue in CIELAB is a pale pinkish color."
Source: http://eastfarthing.com/blog/2017-09-23-dithering/

Detecting anti-aliased or undersampled text image

I have an image that is essentially a text document (black and white) but due to anti-aliasing/undersampling applied during scanning, the image contains a lot of color, light tone pixels and is thus saved as a full-color image i.e: takes a lot of space.
My goal is to be able to detect Black and White image candidates in order to convert them from full color to B&W which dramatically reduces their size.
Is there a way to detect such anti-aliased/undersampled images? Doing color pixel analysis doesn't help because the colored pixels end up being close in amount to the black pixels... Essentially I want to be able to detect that the colored pixels come from anti-aliasing/undersampling a black & white image and not from a picture type image.
Here is an example image:
As you can see there are many more colors than just black. However this image is a good candidate for Black & White / Greyscale conversion instead of full color. How can I detect such images? Please note that in this example the colors tend to be on the grey side but there are many cases where they are cyan or brown etc.
I think it is a valid question. I don't have 50 reputation to post a comment so I will post this as an answer.
Basically, in a black and white anti-aliased image the various grey colors are opacity differences of the black color. If we observe those pixels they will be like these listed below. So, if the operation is a color manipulation then apply the same opacity picked up from those grey pixels to the new color.
rgba(0,0,0,0.6)
rgba(0,0,0,0.9)
rgba(0,0,0,0.5)
rgba(0,0,0,0.9)
rgba(0,0,0,0.6)
rgba(0,0,0,0.1)
rgba(0,0,0,0.5)
In my opinion, the pixels other than grey, in this example image, cyan and brown as it appears can be safely ignored because they seemed like not part of the original text. If there were a few more example images of non grey pixels would have been good. But if we cannot ignore them just need to get the pixel opacity and apply the same color manipulation. In other words we treat them as black pixels.

Algorithm for smart floodfill in raster image

I'm trying to implement flood fill method for raster image.
For center pixels it's easy and works correct, but the problem is to fill pixels near border, which have different color.
For example, if draw Black figure on White background, some border pixels will have kind of gray color instead of black (for smoothing).
Image editors (like paint.net) during floodfill fixes it changing these pixels to some middle color between old and new one. Here I filled figure in red color, and gray pixels became in red gradient
I need to know method or algorithm how gray pixels became in kind of color to fill (here it's red, but can be any) using RGB pixel manipulation.
Thanks for any help.
So, for similar effect like in example we just need to use & operation between old and new color.
For RGB color:
resultColor.R = (byte)(oldColor.R & newColor.R);
resultColor.G = (byte)(oldColor.G & newColor.G);
resultColor.B = (byte)(oldColor.B & newColor.B);
If RGB color is Int number:
resultColor = oldColor & newColor;
It will not be exactly same color as in example below but pretty similar.

Determining rgb planes of a color image

What is meant by red,green or blue plane of a color image?How do we generate the red plane?how is it different from the other planes?Please explain the logic behind generating these planes?
Every pixel in a normal colour image is made up of a red part, a green part and a blue part - hence RGB image. Typically there is one byte for the red part at each location in the image, one for green and one for blue. As there is a byte for each pixel location, the red can vary between 0 (zero) which means "no red" and 255 which means "full red". Likewise the green and blue. So an image where all the pixels are
Red=255, Green=0, Blue=0 will look very bright red
Red=0, Green=255, Blue=0 will look very green
and a pixel where R=G=B will look grey, and if R=G=B=16 it will be very dark grey, and if R=G=B=240 it will be very light/bright grey.
So, the "red plane" is merely an image that only shows the red part of each pixel, or how much red there is in each pixel.
Here is a rose:
and here is the red plane, and you can see that where the rose is very red, the red plane is very bright meaning there is lots of red.:
Here is the green plane (you can see the green leaf on the right is bright):
and the blue plane (you can see the blueish petals on the left are bright):
If you want to separate the color channels (planes), it is very easy in ImageMagick to get the red plane, for example:
convert rose: -channel red -separate red.jpg
ImageMagick is free and amazing - available here.
Simple answer:
Say you read a 480x640 color image, like so:
A = imread('image.jpg');
The matrix A has dimensions 480 x 640 x 3. The third dimension are three 480 x 640 planes, or color channels:
red = A(:,:,1)
green = A(:,:,2)
blue = A(:,:,3)
Now you can go to the link #Trilarion gave in the comments and look at the portion about Truecolor Images.
If I understand your comment, you want to know how a CCD of a camera catch the chroma of each color.
Have a look to color space
And maybe about wavelength of colors (Look at the table of color frequency/wavelength for more informations)
And camera CDD to understand how camera catch those wavelenght and create color channel of an image.

Best natural way of coloring an icon/sprite

I wanna to color a sprite/icon with a transparent background and with shadows. I tried to shift the hue to all pixels but it looks not so natural and I have problems with the black and the white colors in an image. If an image tend to be black shifting the hue do not change the black in red or another color even shifting by 360 degrees.
Tried to color addicting and subtracting color and even in that case the black and the white tend to be colored or disappears at all.
Maybe should I put an image on the icon to achieve the coloring effect ?
Any suggestions on how to proceed.
I lost.
You've been asking a lot about this hue shifting thing, so I figured I'd try to work out an example: http://jsfiddle.net/EMujN/3/
Here's another that uses an actual icon: http://jsfiddle.net/EMujN/4/
There's a lot in there. There's a huge data URL which you can ignore unless you want to replace it. Here's the relevant part where we modify HSL.
//SHIFT H HERE
var hMod = .3;
hsl[0]=(hsl[0]+hMod)%1;
//MODIFY S HERE
var sMod = .6;
hsl[1]=Math.max(0,Math.min(1,
hsl[1]+sMod
));
//MODIFY L HERE
var lMod = 0;
hsl[2]=Math.max(0,Math.min(1,
hsl[2]+lMod
));
I've converted to HSL because it's a lot easier to accomplish what you want in that color space than RGB.
Without getting any more complex, you have three variables you can tune: how much to add to either Hue, Saturation, or Lightness. I have the lightness variable set to 0 because any higher and you will see some nasty JPEG artifacts (if you can find a decent .png that would be better, but I went with the first CC night image I could find).
I think the hue shift (yellow to green) looks pretty good though and I have maxed out the saturation, so even a normally white light appears bright purple. Like I said in my comment, you will need to increase the lightness and saturation if you want to colorize patches of black and white. Hopefully, you can figure out what you need from this example.
image used: http://commons.wikimedia.org/wiki/File:Amman_(Jordan)_at_night.jpg
I found a better solution by myself which can solve the problem with the black and white.
So basically the solution can be solved in multiple steps. Here I will define the steps. Later I'll provide some working code:
Get the image
Calculate the predominant color, averaging the image pixels or simply providing an input RGB value which is the predominant that your eye can catch.
If the predominant tends to be black or white, or both, the image has to be recolored with an addictive or subtractive method, addictive if black, subtractive if white. So basically all RGB pixels should be attenuated or sharpened until RED. I think that the best solution should be RED, because RED is first in the HUE scale, and this can help when we will hue-shift the pixels.
To have a unique algorithm which can work with different kind of images, not only black predominant or white, ideally the input the non-black and non-white predominant images should be pre-hueshifted manually, using photoshop or with another algorithm in a way that the new predominant color results to be RED too
After that the Hue shifting coloring is straighforward. We know that the predominant color is RED for all the images, and we'll shift the HUE values with a difference between the HSV value of the desired color and the HSV of the predominant color (RED).
Game over. We have a pretty universal way to color different images with hue shifting in a natural way.
Another question could be how to authomatically pre-shift the input images which predominant color is not black or white.
But this is another question.
Why this coloring method could be considered natural. Simply consider one thing. Generally the non dominant black or white colors are part of the shadows and light which gives a 3D feel to the images. On the other hand if my shoes are 100% black and i will tint them with some colors, they will no more be black. Color the dominant black cannot be achieved simply shifting the HSV parameters but other steps should be performed. The steps are the above described.

Resources