Example #1
0
        private async void GenerateMosaic(object sender, RoutedEventArgs e)
        {
            var availableSources = sources.ToList();

            var sourcePixels = sampledBitmap.Pixels.Select(p => ColorSpaces.CieLab.ConvertFromStandardRgb(p)).ToArray();

            ColorClusteredBitmap[] targetPixelImages = new ColorClusteredBitmap[sourcePixels.Length];

            int progressIndex = 0;
            var timer         = InitializeProgress(targetPixelImages.Length * 2, () => progressIndex);

            await Task.Run(() =>
            {
                for (; progressIndex < sampledBitmap.Pixels.Length; progressIndex++)
                {
                    targetPixelImages[progressIndex] = FindBestMatchAndRemove(sourcePixels[progressIndex], ColorSpaces.CieLab, availableSources);
                }
            });

            FinishProgress(timer);

            const double maxSize   = 23000;
            double       scaleXFit = Math.Min(1, maxSize / (sampledBitmap.Width * averageWidth));
            double       scaleYFit = Math.Min(1, maxSize / (sampledBitmap.Height * averageHeight));
            double       scaleFit  = Math.Min(scaleXFit, scaleYFit);

            int cellWidth  = (int)(averageWidth * scaleFit);
            int cellHeight = (int)(averageHeight * scaleFit);

            var output = await CreateOutputBitmap(targetPixelImages, sampledBitmap.Width, sampledBitmap.Height, (int)(averageWidth *scaleFit), (int)(averageHeight *scaleFit));

            SimplifiedBitmap.Source = output;
            SimplifiedBitmap.Width  = output.PixelWidth;
            SimplifiedBitmap.Height = output.PixelHeight;
        }
Example #2
0
        private float DistanceTo(ColorClusteredBitmap other, IReadOnlyList <int> indexLookup)
        {
            float distance = 0;

            for (int i = 0; i < this.Histogram.Colors.Count; i++)
            {
                float thisWeight  = (float)this.Histogram.Colors[i].PixelCount / this.Histogram.PixelCount;
                float otherWeight = (float)other.Histogram.Colors[indexLookup[i]].PixelCount / other.Histogram.PixelCount;

                float distanceSquared = Vector3.DistanceSquared((Vector3)this.Histogram.Colors[i].Color.ToCieLab(), (Vector3)other.Histogram.Colors[indexLookup[i]].Color.ToCieLab());

                distance += distanceSquared * (thisWeight + otherWeight) / 2;
            }

            return(distance);
        }
Example #3
0
        private async void PopulateImagesAsync(string originalImages, string computedImages)
        {
            string[] originalFilePaths  = Directory.GetFiles(originalImages, "*.png").Concat(Directory.GetFiles(originalImages, "*.jpg")).ToArray();
            string[] computedFilesPaths = Directory.GetFiles(computedImages, "*.png");

            Tuple <string, string>[] joinedPaths = originalFilePaths.Join(computedFilesPaths, o => Path.GetFileNameWithoutExtension(o), i => GetPrefix(i), (o, i) => Tuple.Create(o, i)).ToArray();

            ColorClusteredBitmap[] bitmaps = new ColorClusteredBitmap[originalFilePaths.Length];

            int progress = 0;
            var timer    = InitializeProgress(joinedPaths.Length, () => progress);

            long totalWidths  = 0;
            long totalHeights = 0;

            await Task.Run(() =>
            {
                Parallel.For(0, joinedPaths.Length, i =>
                {
                    string histogramFile = Path.Combine(Path.GetDirectoryName(joinedPaths[i].Item2), "colorHistograms", $"{Path.GetFileNameWithoutExtension(joinedPaths[i].Item2)}.json");
                    if (File.Exists(histogramFile))
                    {
                        WeightedColorSet set = JsonConvert.DeserializeObject <WeightedColorSet>(File.ReadAllText(histogramFile));
                        bitmaps[i]           = new ColorClusteredBitmap(joinedPaths[i].Item1, joinedPaths[i].Item2, set);

                        Interlocked.Add(ref totalWidths, bitmaps[i].Histogram.PixelWidth);
                        Interlocked.Add(ref totalHeights, bitmaps[i].Histogram.PixelHeight);
                    }

                    Interlocked.Increment(ref progress);
                });
            });

            FinishProgress(timer);

            foreach (ColorClusteredBitmap result in bitmaps.Where(b => b != null))
            {
                sources.Add(result);
            }

            averageWidth       = (int)(totalWidths / sources.Count);
            averageHeight      = (int)(totalHeights / sources.Count);
            averageAspectRatio = (float)totalWidths / totalHeights;
        }
Example #4
0
        public float DistanceTo(ColorClusteredBitmap other, bool usePermutations)
        {
            float distance = float.MaxValue;

            if (usePermutations)
            {
                foreach (var permutation in Permutation.GetPermutations(this.Histogram.Colors.Count))
                {
                    float newDistance = DistanceTo(other, permutation);
                    if (newDistance < distance)
                    {
                        distance = newDistance;
                    }
                }
            }
            else
            {
                distance = DistanceTo(other, Permutation.GetPermutations(this.Histogram.Colors.Count).First());
            }

            return(distance);
        }