Definition of dominant tones in the image


A very long time ago, when my knowledge in PHP was at the level of operations and output, and I found a very useful class written by Kalpeh Gamit, his site was unavailable for a long time, so unfortunately I can’t leave contacts. The class is distributed under the name GetImageColor and under the GPL 2.0 license.

I used this class often. It takes as an input parameter an image (only in JPEG format, but is supplemented by everyone else in a minute), the number of colors returned and the processing step. The script reads the color from the photo with a given step and enters it into an array of colors. The resulting array is sorted by occurrence of colors and only the specified number of colors is returned.

A very convenient script for many tasks. Personally, I needed it in the first version of the Photo Kiosk, using a script I determined single-color photos and did not allow them to be uploaded to the server (too dark, overexposed, etc.). Later in LetPrint, I used it to determine sheet fullness and color.

Today I saw an article on Habré:

Interested in this. The image was chosen not just common colors, but dominant or contrasting tones. Recalling what the class would produce, I realized that a different solution was needed.


Actually, a similar script may work for them, but they add the final color options manually, which most likely happens because the presence of the selected colors is not so dominant in the picture. And the colors are too soft. But maybe they are just smoothing out similar colors, which I noticed.

The next stage is an attempt to achieve smoothing. We need an algorithm that would process an array with the available colors, select similar colors in it and find a smooth color, and so on, until 5 primary ones were selected.

Writing such an algorithm was not difficult, but searching for similar ones slowed me down a bit. Although I did not understand it for a long time, I still easily found a makeshift solution.

Our color consists of three components: R + G + B. All these values ​​are from 0 to 255. The colors 250,100,100 and 240,90.90 are similar, but the second is darker than the first, but nonetheless they are similar. The color 245,100,100 is also similar to the first two, but to a lesser extent. Actually, here the error begins. The first two colors are similar, but similar and 255,255,255 and 0,0,0 and it immediately discards black and white photographs. Also, due to the similarity of the first two and the third, shades are discarded. But we are ready for such sacrifices.

The number of similarities is | RG |. | RB |. | BG |, and to introduce similar shades, the difference itself is also processed dif = round (round (| RG | / pogr) * pogr). By the pogr coefficient, we introduce an error. For example, if pogr = 10, then the colors 254,180,35 and 234,163,19 are similar. The larger the error, the more similar shades we will combine.

After you need to consider the weight of the color, smooth the array into a single color. We have an array of similar colors. Each 2 parameters - color and number of occurrences. The smoothed color itself will consist of R = SUM (Ri * mi) / SUM (mi), where mi is the number of occurrences of this color, also with the other components of G and B. This means that since black and white are similar, then as a result of the algorithm, we get gray, which may not be present in the picture, but which will fully reflect the mixture of black and white.

With the resulting array, we do these operations again and again, until we achieve the result. At some point, the algorithm may simply stall, so the sampling error of such pogr increases with each iteration.


As a result, the processing speed of this algorithm is very high. The tones in most cases correspond to those in the figure, but some errors are obvious, which are quite difficult to eliminate in simple ways. By and large, this is pampering, until I figured out where to use it, but for designers it may well be a useful thing.

You can try the algorithm in action here: My
server is weak, so I’ll ask you not to put too much pressure on it. Limitations: JPEG images and weighing no more than 500 KB.

Alternative Solution Methods

The easiest way to solve this problem is the tone catalog. I’ve already come across him somewhere. It offered the most commonly used and pleasant tones. The catalog consisted of several thousand colors, which would be quite enough for this script. The processing, in principle, remains the same, but when smoothing, the color from the catalog is added to the final array, which is similar to the current ones and so on until several colors remain. The advantage of the method is obvious, you will get a color that is good in itself and will not cut the eye and at the same time will reflect the essence of the picture.

The second way is to search by contrast. In this case, the number of occurrences of the color is not considered, but the colors themselves are considered directly. By searching, contrasting shades are selected and smoothed based on their gradients. I have not yet considered this method, but I think if time appears, then I will take it. Its advantage is in the exact essence of the picture. It will give out exactly those colors that are highlighted in the image. Search by contrast in this case will be better than the other two.

UPD_1 Among the uploaded photos there are a lot of naked women. Why would anyone recognize nudity?
UPD_2 4utep found a turnkey solution, but using HSV and a specific set of colors. link
Push_Oksuggested the “color difference formula” approved by CIE. Perhaps she will improve the definition of the likes. So far I have not determined how much. link
UPD_3 Over 1,500 pictures were uploaded per day. Thanks to the habrayuzers for the epic pictures of the past three months and a considerable amount of eroticism. Among the pictures even came across instances asking for an invite. My hoster made me very happy. The site has never crashed and has not slowed down.

Also popular now: