This class implement a KMeans clustering algorithm
        /// <summary>
        /// Test the clustering of data in an Array
        /// </summary>
        private static void ClusterDataSetTestCase()
        {
            double[][] data = DataSample.GetDataSampleFromFile(10000, 25);

            ClusterCollection clusters;
            KMeansParallel kMeans = new KMeansParallel();
            clusters = kMeans.ClusterDataSet(5, data);

            //This line has been commented out. Uncomment it to serialize your object(s)
            KMeansParallel.Serialize(clusters, @"kmeansparallelclusters.xml");
        }
        public string Apply(int k, string fn, string outImagePath)
        {
            Bitmap srcimg = new Bitmap(fn);
            pixels = ImageUtils.BitmapToArray1DIntRGB(srcimg);
            ColorHistogram colorHist = new ColorHistogram(pixels, false);
            int size = colorHist.getNumberOfColors();
            if (size <= k)
                srcimg.Save(outImagePath, ImageFormat.Png);
            else
            {
                double[][] data = new double[size][];

                getRGBData(colorHist, data);
                ClusterCollection clusters;
                KMeansParallel kMeans = new KMeansParallel();
                clusters = kMeans.ClusterDataSet(k, data);
                PaintRGB(srcimg, kMeans, clusters).Save(outImagePath, ImageFormat.Png);
            }
            return outImagePath;
        }
Example #3
0
        public Bitmap PaintYIQ(Bitmap srcimg, KMeansParallel kMeans, ClusterCollection clusters)
        {
            int width = srcimg.Width;
            int height = srcimg.Height;
            BitmapData srcData = srcimg.LockBits(
               new Rectangle(0, 0, width, height),
               ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            int srcOffset = srcData.Stride - width * 3;
            unsafe
            {
                byte* src = (byte*)srcData.Scan0.ToPointer();
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++, src += 3)
                    {
                        int rgb = src[RGB.R] * 256 * 256 + src[RGB.G] * 256 + src[RGB.B];
                        int rgb_mean;

                        if (color_table.ContainsKey(rgb))
                            rgb_mean = (int)color_table[rgb];
                        else
                        {
                            double[] yiq = RGB2YIQ(rgb);
                            double min_dist = Double.MaxValue;
                            int idx = 0;

                            for (int i = 0; i < clusters.Count; i++)
                            {
                                double dist = kMeans.EuclideanDistance(yiq, clusters[i].ClusterMean);
                                if (dist < min_dist)
                                {
                                    min_dist = dist;
                                    idx = i;
                                }
                            }
                            rgb_mean = YIQ2RGB(clusters[idx].ClusterMean[0], clusters[idx].ClusterMean[1], clusters[idx].ClusterMean[2]);
                            color_table.Add(rgb, rgb_mean);
                        }
                        src[RGB.R] = (byte)((rgb_mean & 0xFF0000) >> 16);
                        src[RGB.G] = (byte)((rgb_mean & 0xFF00) >> 8);
                        src[RGB.B] = (byte)(rgb_mean & 0xFF);
                    }
                    src += srcOffset;
                }
            }
            srcimg.UnlockBits(srcData);
            return srcimg;
        }