Generic algorithm to get and set the brightness of a pixel? - algorithm

I've been looking around for a simple algorithm to get and set the brightness of a pixel, but can't find anything - only research papers and complex libraries.
So does anyone know what is the formula to calculate the brightness of a pixel? And which formula should I use to change the brightness?
Edit: to clarify the question. I'm using Qt with C++ but I'm mainly looking for a generic math formula - I will adapt it to the language. I'm talking about RGB pixels of an image in memory. By "brightness", I mean the same as in Photoshop - changing the brightness makes the image more "white" (a brightness value of 1.0 is completely white), decreasing it makes it more "black" (value of 0.0).

Change the color representation to HSV. The V component stands for value and represents the brightness!
Here the algorithm implemented in PHP.
Here is a description of how to do it in C.

What do you mean by a pixel?
You can set the brightness of a pixel in an image with '=' you just need to know the memory layout of the image
To set a pixel on the screen is a little more complicated

Related

How to reconstruct Bayer to RGB from Canon RAW data?

I'm trying to reconstruct RGB from RAW Bayer data from a Canon DSLR but am having no luck. I've taken a peek at the dcraw.c source, but its lack of comments makes it a bit tough to get through. Anyway, I have debayering working but I need to then take this debayered data and get something that looks correct. My current code does something like this, in order:
Demosaic/debayer
Apply white balance multipliers (I'm using the following ones: 1.0, 2.045, 1.350. These work perfectly in Adobe Camera Raw as 5500K, 0 Tint.)
Multiply the result by the inverse of the camera's color matrix
Multiply the result by an XYZ to sRGB matrix fromm Bruce Lindbloom's site (the D50 sRGB one)
Set white/black point, I am using an input levels control for this
Adjust gamma
Some of what I've read says to apply the white balance and black point correction before the debayer. I've tried, but it's still broken.
Do these steps look correct? I'm trying to determine if the problem is 1.) my sequence of operations, or 2.) the actual math being used.
The first step should be setting black and saturation point because you need to apply white balance looking after saturated pixels in order to avoid magenta highlights:
And before demosaicing, apply white balacing. See here (http://www.guillermoluijk.com/tutorial/dcraw/index_en.htm) how applying white balance before demosaicing introduce artifacts.
After the first step (debayer) you should have a proper RGB image with right colors. Remaining steps are just cosmetics. So I'm guessing there's something wrong at step one.
One problem could be the Bayer pattern you're using to generate RGB image is different from the CFA pattern of the camera. Match sensor alignment in your code to that of the camera!

What algorithm does Photoshop use to desaturate an image?

I have been trying to figure out what kind of mathematical algorithm that programs like Photoshop use when they desaturate each pixel of an image. By desaturate, I mean turning a colored image into a greyscale image and still maintaining the colorspace. I am still talking about an RGB image but one that has just been desaturated in color and is now black and white.
Does anyone know what kind of algorithm is used?
Desaturating is pretty simple. The usual is something like G*.59+R*.3+B*.11
Photoshop also has a B&W conversion tool that (basically) lets you select the factor for each. For example, you can get the effect of a red filter by increasing the percentage of red, and decreasing the green and blue to match.
As noted in the comments, the accepted answer is not the formula used by Photoshop. The real Photoshop desaturate formula is average of minimum RGB and maximum RGB components.
float bw = (fminf(r, fminf(g, b)) + fmaxf(r, fmaxf(g, b))) * 0.5f;
I believe HSL operations in Photoshop are run in min-max-hue space, so this formula is chosen for speed.

Image Warp Filter - Algorithm and Rasterization

I'd like to implement a Filter that allows resampling of an image by moving a number of control points that mark edges and tangent directions. The goal is to be able to freely transform an image as seen in Photoshop when you use "Free Transform" and chose Warpmode "Custom". The image is fitted into a some kind of Spline-Patch (if that is a valid name) that can be manipulated.
I understand how simple splines (paths) work but how do you connect them to form a patch?
And how can you sample such a patch to render the morphed image? For each pixel in the target I'd need to know what pixel in the source image corresponds. I don't even know where to start searching...
Any helpful info (keywords, links, papers, reference implementations) are greatly appreciated!
This document will get you a good insight into warping: http://www.gson.org/thesis/warping-thesis.pdf
However, this will include filtering out high frequencies, which will make the implementation a lot more complicated but will give a better result.
An easy way to accomplish what you want to do would be to loop through every pixel in your final image, plug the coordinates into your splines and retrieve the pixel in your original image. This pixel might have coordinates 0.4/1.2 so you could bilinearly interpolate between 0/1, 1/1, 0/2 and 1/2.
As for splines: there are many resources and solutions online for the 1D case. As for 2D it gets a bit trickier to find helpful resources.
A simple example for the 1D case: http://www-users.cselabs.umn.edu/classes/Spring-2009/csci2031/quad_spline.pdf
Here's a great guide for the 2D case: http://en.wikipedia.org/wiki/Bicubic_interpolation
Based upon this you could derive an own scheme for splines for the 2D case. Define a bivariate (with x and y) polynomial and set your constraints to solve for the coefficients of the polynomial.
Just keep in mind that the borders of the spline patches have to be consistent (both in value and derivative) to avoid ugly jumps.
Good luck!

Get dominant colors from image discarding the background

What is the best (result, not performance) algorithm to fetch dominant colors from an image. The algorithm should discard the background of the image.
I know I can build an array of colors and how many they appear in the image, but I need a way to determine what is the background and what is the foreground, and keep only the second (foreground) in mind while read the dominant colors.
The problem is very hard especially for gradient backgrounds or backrounds with patterns (not plain)
Isolating the foreground from the background is beyond the scope of this particular answer, but...
I've found that applying a pixelation filter to an image will draw out a really good set of 'average' colours.
Before
After
I sometimes use this approach to derive a pallete of colours with a particular mood. I first find a photograph with the general tones I'm after, pixelate and then sample from the resulting image.
(Thanks to Pietro De Grandi for the image, found on unsplash.com)
The colour summarizer is a pretty sweet spot for info on this subject, not to mention their seemingly free XML Web API that will produce descriptive colour statistics for an image of your choosing, reporting back the following formatted with swatches in HTML or as XML...
what is the average color hue, saturation and value in my image?
what is the RGB colour that is most representative of the image?
what do the RGB and HSV histograms look like?
what is the image's human readable colour description (e.g. dark pure blue)?
The purpose of this utility is to generate metadata that summarizes an
image's colour characteristics for inclusion in an image database,
such as Flickr. In particular this tool is being used to generate
metadata for Flickr's Color Fields group.
In my experience though.. this tool still misses the "human-readable" / obvious "main" color, A LOT of the time. Silly machines!
I would say this problem is closer to "impossible" than "very hard". The only approach to it that I can think of would be to make the assumption that the background of an image is likely to consist of solid blocks of similar colors, while the foreground is likely to consist of smaller blocks of dissimilar colors.
If this assumption is generally true, then you could scan through the whole image and weight pixels according to how similar or dissimilar they are to neighboring pixels. In other words, if a pixel's neighbors (within some arbitrary radius, perhaps) were all similar colors, you would not incorporate that pixel into the overall estimate. If the neighbors tend to be very different colors, you would weight the pixel heavily, perhaps in proportion to the degree of difference.
This may not work perfectly, but it would definitely at least tend to exclude large swaths of similar colors.
As far as my knowledge of image processing algorithms extends , there is no certain way to get the "foreground"; it is only possible to get the borders between objects. You'll probably have to make do with an average, or your proposed array count method. In that, you'll want to give colours with higher saturation a higher "score" as they're much more prominent.

How does Google's image color search work?

Let's say I query for
http://images.google.com.sg/images?q=sky&imgcolor=black
and I get all the black color sky, how actually does the algorithm behind work?
Based on this paper published by Google engineers Henry Rowley, Shumeet Baluja, and Dr. Yushi Jing, it seems the most important implication of your question about recognizing colors in images relates to google's "saferank" algorithm for pictures that can detect flesh-tones without any text around it.
The paper begins by describing by describing the "classical" methods, which are typically based on normalizing color brightness and then using a "Gaussian Distribution," or using a three-dimensional histogram built up using the RGB values in pixels (each color is a 8bit integer value from 0-255 representing how much . of that color is included in the pixel). Methods have also been introduced that rely on properties such as "luminance" (often incorrectly called "luminosity"), which is the density of luminous intensity to the naked eye from a given image.
The google paper mentions that they will need to process roughly 10^9 images with their algorithm so it needs to be as efficient as possible. To achieve this, they perform the majority of their calculations on an ROI (region of interest) which is a rectangle centered in the image and inset by 1/6 of the image dimensions on all sides. Once they've determined the ROI, they have many different algorithms that are then applied to the image including Face-Detection algs, Color Constancy algs, and others, which as a whole find statistical trends in the image's coloring and most importantly find the color shades with the highest frequency in the statistical distribution.
They use other features such as Entropy , Edge-Detection, and texture-definitions to
In order to extract lines from the images, they use the OpenCV implementation (Bradski, 2000) of the probabilistic Hough transform (Kiryati et al., 1991) computed on the edges of the skin color connected components, which allows them to find straight lines which are probably not body parts and additionally allows them to better determine which colors are most important in an image, which is a key factor in their Image Color Search.
For more on the technicalities of this topic including the math equations and etc, read the google paper linked to in the beginning and look at the Research section of their web site.
Very interesting question and subject!
Images are just pixels. Pixels are just RGB values. We know what black is in RGB, so we can look for it in an image.
Well, one method is, in very basic terms:
Given a corpus of images, determine the high concentrations of a given color range (this is actually fairly trivial), store this data, index accordingly (index the images according to colors determined from the previous step). Now, you have essentially the same sort of thing as finding documents containing certain words.
This is a very, very basic description of one possible method.
There are various ways of extracting color from an image, and I think other answers addressed them (K-Means, distributions, etc).
Assuming you have extracted the colors, there are a few ways to search by color. One slow, but obvious approach would be to calculate the distance between the search color and the dominant colors of the image using some metric (e.g. Color Difference), and then weight the results based on "closeness."
Another, much faster, approach would be to essentially downscale the resolution of your color space. Rather than deal with all possible RGB color values, limit the extraction to a smaller range like Google does (just Blue, Green, Black, Yellow, etc). Then the user can search with a limited set of color swatches and calculating color distance becomes trivial.

Resources