Esempio n. 1
0
        private List <byte[]> get_palette(List <byte[]> samples1)
        {
            //def get_palette(samples, options, return_mask= False, kmeans_iter= 40):
            //'''Extract the palette for the set of sampled RGB values. The first
            //palette entry is always the background color; the rest are determined
            //from foreground pixels by running K - means clustering.Returns the
            //palette, as well as a mask corresponding to the foreground pixels.
            var bg_color = get_bg_color(samples1, 6);
            var fg_mask  = get_fg_mask(bg_color, samples1);

            //var kmeans_iter = 40; // Can't specify this at run time. 44 iterations are run versus 40 in python.
            var kmeans = new Accord.MachineLearning.KMeans(num_colors - 1);

            //Convert List of Byte[] to double[][] for Accord KMeans
            var doubleSamples = new double[samples1.Count][];

            for (int i = 0; i < samples1.Count; i++)
            {
                doubleSamples[i] = new double[] { samples1[i][0], samples1[i][1], samples1[i][2] }
            }
            ;

            // Filter samples to only true items
            var countOfTrue     = fg_mask.Where(x => x == true).Count();
            var filteredSamples = new double[countOfTrue][];
            var c = 0;

            for (int i = 0; i < fg_mask.Count; i++)
            {
                if (fg_mask[i])
                {
                    filteredSamples[c] = new double[] { doubleSamples[i][0], doubleSamples[i][1], doubleSamples[i][2] };
                    c++;
                }
            }

            // Accord KMeans returns different values than scipy kmeans.
            var clusters = kmeans.Learn(filteredSamples);
            var palette1 = clusters.Centroids.ToList();

            palette1.Insert(0, new double[] { bg_color.R, bg_color.G, bg_color.B });

            var bytePal = new List <byte[]>();

            for (int i = 0; i < palette1.Count; i++)
            {
                bytePal.Add(new byte[] { (byte)palette1[i][0], (byte)palette1[i][1], (byte)palette1[i][2] });
            }

            return(bytePal);
        }
Esempio n. 2
0
        /// <summary>
        /// Get the palette of an image
        /// </summary>
        /// <param name="image"></param>
        public static List <Color> GetPalette(Image image, int paletteSize)
        {
            PaletteManager.PaletteSize = paletteSize;

            // Get data for kmeans clustering
            KMeansData data = GetKMeansData(image.Pixels.Select(p => p.Color).ToList());

            // Format color data for KMeans (using Lab color space)
            double[][] formattedData = FormatData(data.means);
            double[][] centroids     = FormatData(data.centroids);

            // Perform KMeans w/additional black datapoint
            Accord.MachineLearning.KMeans kMeans = new Accord.MachineLearning.KMeans(PaletteSize + 1);
            kMeans.Centroids = centroids;

            var clusters = kMeans.Learn(formattedData);

            int[] labels = clusters.Decide(formattedData);

            // Get palette values
            double[][]   doublePalette = kMeans.Centroids;
            List <Color> Palette       = new List <Color>();

            foreach (double[] lab in doublePalette)
            {
                Palette.Add(new Color(L: lab[0], a: lab[1], b: lab[2]));
            }

            // Sort palette by luminance
            Palette = Palette.OrderBy(p => p.L).ToList();

            // Take all actual palette members
            Palette = Palette.TakeLast(PaletteSize).ToList();

            return(Palette);
        }