private static Difference[,] CalculateDistances(Color[][] palettes)
        {
            // Combination of each palette with each palette except with itself (diagonal)
            Difference[,] distances = new Difference[palettes.Length, palettes.Length];

            // Convert palettes to labcolor space to compute difference
            LabColor[][] labPalettes = new LabColor[palettes.Length][];
            for (int i = 0; i < palettes.Length; i++)
            {
                labPalettes[i] = ColorConversion.ToLabPalette <Color>(palettes[i]);
            }

            // Compute every possible difference
            for (int i = 0; i < palettes.Length; i++)
            {
                for (int j = 0; j < palettes.Length; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    distances[i, j]            = new Difference();
                    distances[i, j].SrcPalette = i;
                    distances[i, j].DstPalette = j;
                    distances[i, j].Distance   = PaletteDistance.CalculateDistance(
                        labPalettes[i], labPalettes[j]);
                }
            }

            return(distances);
        }
        private static Difference[] CalculateDifferentsColors(Color[][] palettes, int idx)
        {
            // Combination of the palette with other palette except with itself
            Difference[] distances = new Difference[palettes.Length - 1];

            // Compute every possible difference
            int j = 0;

            for (int i = 0; i < palettes.Length; i++)
            {
                if (idx == i)
                {
                    continue;
                }

                distances[j]            = new Difference();
                distances[j].SrcPalette = idx;
                distances[j].DstPalette = i;
                distances[j].Distance   = PaletteDistance.CalculateDifferentsColors(
                    palettes[idx], palettes[i]);
                j++;
            }

            return(distances);
        }
        protected override void PreQuantization(Emgu.CV.Image <Color, byte> image)
        {
            this.image = image;

            // If only there is one, do nothing
            if (this.palettes.Length == 1)
            {
                base.PreQuantization(image);
                return;
            }

            // Extract a palette from the image removing transparent colors (not approximated)
            this.compareQuantization.TileSize = this.TileSize;
            this.compareQuantization.Quantizate(image);
            Color[] comparePalette = this.compareQuantization.Palette.
                                     Where(c => c.Alpha == 255).ToArray();
            LabColor[] compareLabPalette = ColorConversion.ToLabPalette <Color>(comparePalette);

            // Compare all possible palettes to get the similar one
            double minDistance = Double.MaxValue;

            for (int i = 0; i < palettes.Length && minDistance > 0; i++)
            {
                double distance = PaletteDistance.CalculateDistance(
                    compareLabPalette, this.labPalettes[i]);
                if (distance < minDistance)
                {
                    this.SelectedPalette = i;
                    minDistance          = distance;
                }
            }

            // Set the palette...
            this.Palette = this.palettes[this.SelectedPalette];

            // ... and run the FixedPaletteQuantization
            base.PreQuantization(image);
        }