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?
Related
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!
I'm looking for methods for histogram blurring in image processing. I found this old thread but the answers there does not solve my case.
One answer there suggest that
There is actually nothing called Histogram blurring.
so Is there any way for histogram blurring in image processing?
[edit1] some more info
image size is 3880x2592.
I want to blur with gaussian blur with radius about 15-20 (*pixels?).
I am using 256×16bit 8ea(*?) single ports memories.
I want to imlement this on FPGA
if by blur you mean smooth (removing high frequencies) then you can use any smooth filter or algorithm (most of them are based on FIR low pass filters)
if your question is what to smooth then the answer is same as in the question you linked it depends on what you need:
if you need smoothed histogram for some computation then smooth histogram directly and leave image be as is
if you need the image colors to be smoothed then smooth image and recompute histogram
sometimes is hard to smooth image to get smoothed histogram
(due to slow bleeding of colors or by too big data loss)
In that case you can smooth the histogram (remembering the original) then compute the area change for each color and statistically recolor whole image (it is not an easy task).
Pick (random) pixel of color a which area needs to be decreased and recolor it to closest color b thats area needs to be increased
update area of booth colors
loop until areas are matching ...
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.
Sometimes I have a true colored image, by using dithering algorithm, I can reduce the color to just 256. I want to know how the dithering algorithm achieve this.
I understand that dithering can reduce the error, but how can the algorithm decrease color depth, especially from true color to just 256 colors or even less.
Dithering simulates a higher color depth by "mixing" the colors in a defined palette to create the illusion of a color that isn't really there. In reality, it's doing the same thing that your computer monitor is already doing: taking a color, decomposing it into primary colors, and displaying those right next to each other. Your computer monitor does it with variable-intensity red, green, and blue, while dithering does it with a set of fixed-intensity colors. Since your eye has limited resolution, it sums the inputs, and you perceive the average color.
In the same way, a newspaper can print images in grayscale by dithering the black ink. They don't need lots of intermediate gray colors to get a decent grayscale image; they simply use smaller or larger dots of black ink on the page.
When you dither an image, you lose information, but your eye perceives it in largely the same way. In this sense, it's a little like JPEG or other lossy compression algorithms which discard information that your eye can't see.
Dithering by itself does not decrease the number of colors. Rather, dithering is applied during the process of reducing the colors to make the artifacts of the color reduction less visible.
A color that is halfway between two other colors can be simulated by a pattern that is half of one color and half of the other. This can be generalized to other percentages as well. A color that is a mixture of 10% of one color and 90% of the other can be simulated by having 10% of the pixels be the first color and 90% of the pixels be the second. This is because the eye will tend to consider the random variations as noise and average them into the overall impression of the color of an area.
The most effective dithering algorithms will track the difference between the original image and the color-reduced one, and account for that difference while converting future pixels. This is called error diffusion - the errors on the current pixel are diffused into the conversions of other pixels.
The process of selecting the best 256 colors for the conversion is separate from dithering.
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".