A Simple Algorithm for calculating the main color of an image (C # source code)

Source: Internet
Author: User

Some friends consulted the algorithm for analyzing the main color of the image a few days ago. I didn't have any in-depth research on this part. After referring to some small code, I wrote a very simple little tool myself, share it with you.

The interface is as follows:

The principle of the algorithm is very simple, that is, to calculate the distribution of various colors in the image, and then take the first N colors as the principal component.

Of course, in fact, if we make statistics on the 256 levels of each channel of the image, the result may be meaningless, therefore, we usually need to first hide the first 256 color-order linearity to a smaller color-order range.

The main code is as follows:

Static unsafe class Statistics {//'******************************** **************************************** * **************** // '* Development Date: // '** OPERATOR: laviewpbt //' ** contact info: 33184777 // '** modification date: //' ** version: version 1.1.1 // '*** do not delete the above information //'************************ **************************************** * ********************** [StructLayout (LayoutKind. sequential)] public struct MajorColor: IComparable <MajorColor> {internal int Color; internal int Amount; public MajorColor (int Color, int Amount) {this. color = Color; this. amount = Amount;} public int CompareTo (MajorColor obj) {return this. amount. compareTo (obj. amount) ;}/// http://www.coolphptools.com/color_extract // http://www.wookmark.com/image/268753/30-inspiring-examples-of-levitation-photography-inspirationfeed-com public static List <MajorColor> PrincipalColorAnalysis (Bitmap Bmp, int PCAAmount, int Delta = 24) {List <MajorColor> MC = new List <MajorColor> (); int X, Y, Width, Height, Stride, Index, TotalColorAmount = 0; int HalfDelta; byte * Pointer, scan0; BitmapData Bmp DATA = Bmp. lockBits (new Rectangle (0, 0, Bmp. width, Bmp. height), ImageLockMode. readWrite, PixelFormat. format24bppRgb); Height = Bmp. height; Width = Bmp. width; Stride = BMP data. stride; Scan0 = (byte *) BMP data. scan0; int [] Table = new int [256*256*256]; int [] NonZero = new int [Width * Height]; int [] Map = new int [256]; if (Delta> 2) HalfDelta = Delta/2-1; else HalfDelta = 0; for (Y = 0; Y <256; Y ++) {Map [Y] = (Y + HalfDelta)/Delta) * Delta; if (Map [Y]> 255) Map [Y] = 255 ;} for (Y = 0; Y <Height; Y ++) {Pointer = Scan0 + Stride * Y; for (X = 0; X <Width; X ++) {Index = (Map [* Pointer] <16) + (Map [* (Pointer + 1)] <8) + Map [* (Pointer + 2)]; if (Table [Index] = 0) // This color {NonZero [TotalColorAmount] = Index has not been displayed; // records the position with a color, at the same time, the color TotalColorAmount ++ is recorded. // The total number of colors + 1} Table [Index] ++; // the corresponding number of colors plus 1 Pointer + = 3; // move to the next pixel} MajorColor [] Result = new MajorColor [TotalColorAmount]; for (Y = 0; Y <TotalColorAmount; Y ++) {Result [Y]. amount = Table [NonZero [Y]; Result [Y]. color = NonZero [Y];} Array. sort (Result); // The sorting algorithm provided by the system is faster than the algorithm written by the system. reverse (Result); for (Y = 0; Y <PCAAmount; Y ++) MC. add (new MajorColor (Result [Y]. color, Result [Y]. amount); Bmp. unlockBits (BMP data); GC. collect (); // immediately release the allocated 64 MB memory return MC ;}}

In fact, I have been looking for an algorithm that does not occupy a lot of memory and is fast, but I have never thought of a good way. In the above Code, 64 MB memory is allocated for index counting. Although such a large memory usage is required for small images, I found that, it is much faster than Dictionary-based statistical methods such as Dictionary.

I always think that I can write algorithms faster than the system, but I finally chose the simple method in the above Code. While sorting Amount, the Color value also follows suit.

In this Code that occupies a large amount of memory, I think it is necessary to immediately call GC. Collect () to release the memory.

The Delta value does not seem to be well determined. It can only be determined by the test. Generally, the value between 16 and 32 is reasonable.

There are also some good algorithms in the two reference links, but the code in it is PHP. It is difficult to rewrite it to C, if you are interested, you can learn it by yourself.

From my personal understanding, I think this color principal component analysis can also use the eight-tree algorithm similar to that used to find the best index table during color-to-index conversion; you can also use clustering algorithms such as FCM or KMEANS. When the time is sufficient, I will go back to the actual verification.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.