Algorithm for most visually dominant pixel colour [duplicate] - algorithm

I'm looking for an idea for getting the most representative color in a grid of pixels. There is any algorithm for this? I'm not sure if the most representative is one of the colors appearing in the grid of is the average af all the pixels better?
alt text http://www.stan.mx/images/stackoverflowPixels.gif

Have a look at some color quantization algorithms. I found them to be the most effective method to generate palettes from photographs. Also, most image manipulation/processing libraries should have some fast quantization built in.

You are probably looking at "average" as percepted by human. First you need to change you colors representation in a color space that is specially designed to be
"perceptually uniform" (for calculation of color "distances") Lab* link text
Then, each color is a point in 3D color space. Now you can find the "center" of the cloud of points and this is the "most representative color".

Related

How to detect colors under different illumination conditions

I have a bunch of images of clothes of many colors and I want to detect the colors of each image. Say that I have a blue skirt image in daylight conditions and I can get the correct color through RGB distributions. However, at night it's difficult to tell the color and the "blue" is recognized as "black". It's very hard to make a unified standard to specify colors through RGB distributions.
As such, I am wondering is there a way or algorithm to detect colors under different illuminations?
BTW: I also tried HSV color space and the results were not good.
That's a very hard problem and it's still trying to be solved today. The gist of it is to find a colour quantization using a representative set of basic colours of an image that is robust against different external stimuli... lighting, shade, poor illumination etc.
Unfortunately I can't suggest any one algorithm that would do the work for you for all cases. However, one algorithm that has worked for me in the past was when I was doing work in image retrieval. Specifically, the work by Jiebo Luo and David Crandall from Kodak Research Labs: http://vision.soic.indiana.edu/papers/compoundcolor2004cvpr.pdf
The basic algorithm is to take a look at the ISCC-NBS colour palette set. Also, this link is much more fruitful: https://www.w3schools.com/colors/colors_nbs.asp. It is a set of 267 colours that are representative of the colours that we see in modern society today. Usually when we describe colours, we have a set of one or more adjectives, followed by the dominant hue. For example, that shirt is a darkish pale blue, or a light bright yellow, etc. The beauty of this algorithm is that when the colour in question is subject to different external stimuli, we have all of these adjectives that give meaning to the colour, but at the end of the day, the last part of the colour - the dominant hue - is what we're after.
Each of these colours has an associated RGB value. These colours are transformed into the CIE Lab colour space which form a 267 CIE Lab lookup table.
To classify a particular input colour, you would transform this input's RGB values into the CIE Lab colour space, then determine the closest colour to this lookup table. It has been shown that the Euclidean distance between two colours in the CIE Lab colour space best represents the difference in human perception of colours. Once we determine which location in the lookup table the colour is closest to, we strip out all of the adjectives and see what the dominant hue is and we thus classify that colour accordingly.
For example, if we had a RGB pixel and we converted it to Lab, then found that the closest colour was bright yellow, we would remove the "bright" and the final colour that is representative of that RGB pixel would be yellow.
Therefore, the final algorithm is this:
Find the ISCC-NBS colour set's RGB values and convert to CIE Lab and create a lookup table, which I call LUT1. In Python for example, you could simply make this a 2D list or 2D NumPy array.
Create another lookup that stores the dominant hue for each of the colours in the ISCC-NBS colour set - so strip out all of the adjectives and leave the dominant hue, which I call LUT2. In Python for example, you could create a dictionary where the key is the corresponding row of LUT1 and the value would be the actual basic colour itself. Whether it's a string representation or a RGB triplet representing the basic colour is up to you.
For a pixel in question, find the closest ISCC-NBS colour that matches with LUT1 by the Euclidean distance between this pixel's CIE Lab components and the ones in LUT1.
Once we find this location in LUT1, use the same index to index into LUT2 and get the final colour to classify that input pixel's colour.
Hope this helps!

Best Elliptical Fit for irregular shapes in an image

I have an image with arbitrary regions shape (say objects), let's assume the background pixels are labeled as zeros whereas any object has a unique label (pixels of object 1 are labeled as 1, object 2 pixels are labeled as 2,...). Now for every object, I need to find the best elliptical fit of its pixels. This requires finding the center of the object, the major and minor axis, and the rotation angle. How can I find these?
Thank you;
Principal Component Analysis (PCA) is one way to go. See Wikipedia here.
The centroid is easy enough to find if your shapes are convex - just a weighted average of intensities over the xy positions - and PCA will give you the major and minor axes, hence the orientation.
Once you have the centre and axes, you have the basis for a set of ellipses that cover your shape. Extending the axes - in proportion - and testing each pixel for in/out, you can find the ellipse that just covers your shape. Or if you prefer, you can project each pixel position onto the major and minor axes and find the rough limits in one pass and then test in/out on "corner" cases.
It may help if you post an example image.
As you seem to be using Matlab, you can simply use the regionprops command, given that you have the Image Processing Toolbox.
It can extract all the information you need (and many more properties of image regions) and it will do the PCA for you, if the PCA-based based approach suits your needs.
Doc is here, look for the 'Centroid', 'Orientation', 'MajorAxisLength' and 'MinorAxisLength' parameters specifically.

Map image/texture to a predefined uneven surface (t-shirt with folds, mug, etc.)

Basically I was trying to achieve this: impose an arbitrary image to a pre-defined uneven surface. (See examples below).
-->
I do not have a lot of experience with image processing or 3D algorithms, so here is the best method I can think of so far:
Predefine a set of coordinates (say if we have a 10x10 grid, we have 100 coordinates that starts with (0,0), (0,10), (0,20), ... etc. There will be 9x9 = 81 grids.
Record the transformations for each individual coordinate on the t-shirt image e.g. (0,0) becomes (51,31), (0, 10) becomes (51, 35), etc.
Triangulate the original image into 81x2=162 triangles (with 2 triangles for each grid). Transform each triangle of the image based on the coordinate transformations obtained in Step 2 and draw it on the t-shirt image.
Problems/questions I have:
I don't know how to smooth out each triangle so that the image on t-shirt does not look ragged.
Is there a better way to do it? I want to make sure I'm not reinventing the wheels here before I proceed with an implementation.
Thanks!
This is called digital image warping. There was a popular graphics text on it in the 1990s (probably from somebody's thesis). You can also find an article on it from Dr. Dobb's Journal.
Your process is essentially correct. If you work pixel by pixel, rather than trying to use triangles, you'll avoid some of the problems you're facing. Scan across the pixels in target bitmap, and apply the local transformation based on the cell you're in to determine the coordinate of the corresponding pixel in the source bitmap. Copy that pixel over.
For a smoother result, you do your coordinate transformations in floating point and interpolate the pixel values from the source image using something like bilinear interpolation.
It's not really a solution for the problem, it's just a workaround :
If you have the 3D model that represents the T-Shirt.
you can use directX\OpenGL and put your image as a texture of the t-shirt.
Then you can ask it to render the picture you want from any point of view.

Algorithm for "neon glow" graphics programming

I am searching for an article or tutorial that explains how one can draw primitive shapes (mainly simple lines) with a (neon) glow effect on them in the graphical output of a computer program. I do not want to do some sophisticated stuff like for example in modern first pirson shooters or alike. I am more in a search for a simple solution, like the lines in that picture: http://tjl.co/blog/wp-content/uploads/2009/05/NeonStripes.jpg -- but of course drawn by a computer program in my case.
The whole thing should run on a modern smart phone, so the hardware is a bit limited.
I do know a bit about OpenGL, but not too much, so unfortunately I am a bit lost here. Did some research on Google ("glow effect algoritm" and similar), but found either highly complex stuff for 3D games, or tutorials for Photoshop & co.
So what I would really need is an in-depth article on that subject, but not on a very advanced level. I hope thats even possible... I have just started with OpenGL, did some minor graphics programming in the past, but I am a long-year programmer now, so I would understand technical papers in general.
Does anyone of you know of such an article/paper/tutorial/anything?
Thanks in advance for all good advices!
Cheers!
Matthias
Its jus a bunch of lines with different brightness/transperency. Basically, if you want a glow effect for 1px line, in a size of 20 pixels, then you draw 41 lines with width of 1 px. The middle line is with your base colour, other lines get colours that gradiently go from base color to 100% transperency (like in your example) or darkest colour variant (if you have black background, no transparency).
That is it. :)
This isn't something I've ever done, but looking at your example, the basic approach I'd use to try and recreate it would be...
Start with an algorithm for drawing a filled shape large enough to include the original shape and the glow. For example, a rectangle becomes a slightly larger rectangle, but with rounded corners. An infinitessimally-wide line becomes a thickened line with semi-circular caps. Subtract out the original shape (and fill the pixels for that normally).
For each pixel in the glow, the colour depends on the shortest distance to any part of the original shape. This normally reduces to the distance to the nearest point on a line (e.g. one edge of a rectangle).
The distance is translated to a colour value using probably Hue-Saturation-Value or a similar colour scheme, as well as reducing alpha (increasing transparency). For neon glows, you probably want constant hue, decreasing brightness, maybe increasing saturation, and decreasing alpha.
Translate the HSV/whatever colour value to RGB for output. See this question.
EDIT - I should probably have said HSL rather than HSV - in HSL, if L is at it's maximum value, the resulting colour is always white. For HSV, that's only true if saturation is also at zero. See http://en.wikipedia.org/wiki/HSL_and_HSV
The real trick is that even on a phone these days, I'd guess you probably should use hardware (shaders) for this - sorry, I don't know how that's done.
The "painters algorithm" overlaying of gradually smaller shapes that others have described here is also a possibility, but (1) possibly slower, depending on implementation issues, and (2) you may need to draw to an off-screen buffer, with some special handling for the alpha channel, then blit back to the screen to handle the transparency correctly - if you need transparency, that is.
EDIT - Silly me. An alternative approach is to apply a blur to your original shape (in greyscale), but instead of writing out the blurred pixels directly, apply the colour-transformation to each blurred pixel value.
A blur is basically a weighted moving average. Technically, a finite impulse response filter is implemented using a convolution, but the maths for that is a tad awkward and if you just want "a blur" of about the right size, draw a grayscale circle of pixels as your "weights" image.
The blur in this case basically replaces the distance-from-shape calculation.
_____________________
| |
----|---------------------|-----> line
|_____________________|
gradient block
Break up your line into small non-overlapping blocks. Use whatever graphics primitive you have to draw a tilted rectangular gradient: the center is at 100% and the outer edge is at 0%.
Don't draw it on the image yet; you want to blend it with the image. Using regular transparency will just make it look like a random pipe or pole or something (unless you draw a white line, and your background is dark).
Here are two choices of blending mode:
color dodge: [blended pixel value] = (1-[overlay's pixel value]) / [bottom pixel value]
linear dodge: [blended pixel value] = max([overlay's pixel value]+[bottom pixel value], 1)
Then draw the line above the glow.
If you want to draw a curved "neon" line, simply draw it as a sequence of superimposed "neon dots" where each "neon dot" is a small circular image with transparency going from 0% at the origin to 100% at the edge of the circle.

Organizing Images By Color

Maybe you've noticed but Google Image search now has a feature where you can narrow results by color. Does anyone know how they do this? Obviously, they've indexed information about each image.
I am curious what the best methods of analyzing an image's color data to allow simple color searching.
Thanks for any and all ideas!
Averaging the colours is a great start. Just downscale your image to 10% of the original size using a Bicubic or Bilinear filter (or something advanced anyway). This will vastly reduce the colour noise and give you a result which is closer to how humans perceive the image. I.e. a pixel-raster consisting purely of yellow and blue pixels would become clean green.
If you don't blur or downsize the image, you might still end up with an average of green, but the deviation would be huge.
The Google feature offers 12 colors with which to match images. So I would calculate the Lab coordinate of each of these swatches and plot the (a*, b*) coordinate of each of these colors on a two dimensional space. I'd drop the L* component because luminance (brightness) of the pixel should be ignored. Using the 12 points in the (a*, b*) space, I'd calculate a partitioning using a Voronoi Diagram. Then for a given image, I'd take each pixel, calculate its (a*, b*) coordinate. Do this for every pixel in the image and so build up the histogram of counts in each Voronoi partition. The partition that contains the highest pixel count would then be considered the image's 'color'.
This would form the basis of the algorithm, although there would be refinements related to ignoring black and white background regions which are perceptually not considered to be part of the subject of the image.
Average color of all pixels? Make a histogram and find the average of the 'n' peaks?

Resources