public unsafe void CompareImages(Individual individual, Color[,] originalColours)
        {
            double fitness = 0;

            using (Bitmap bit = new Bitmap(_imageWidth, _imageHeight, PixelFormat.Format24bppRgb))
            {
                using Graphics graphics = Graphics.FromImage(bit);
                ImageRenderer.DrawImage(individual, graphics);

                BitmapData bitmapData = bit.LockBits(new Rectangle(0, 0, _imageWidth, _imageHeight), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

                byte bytesPerPixel = 3;

                byte *scan0  = (byte *)bitmapData.Scan0.ToPointer();
                int   stride = bitmapData.Stride;

                for (int j = 0; j < _imageHeight; j++)
                {
                    byte *row = scan0 + (j * stride);

                    for (int i = 0; i < _imageWidth; i++)
                    {
                        int bIndex = i * bytesPerPixel;
                        int gIndex = bIndex + 1;
                        int rIndex = bIndex + 2;

                        byte oRed   = originalColours[i, j].R;
                        byte oGreen = originalColours[i, j].G;
                        byte oBlue  = originalColours[i, j].B;

                        byte gRed   = row[rIndex];
                        byte gGreen = row[gIndex];
                        byte gBlue  = row[bIndex];

                        fitness += Math.Sqrt(Math.Pow(oRed - gRed, 2) + Math.Pow(oGreen - gGreen, 2) + Math.Pow(oBlue - gBlue, 2));
                    }
                }

                bit.UnlockBits(bitmapData);
            }

            individual.Adaptation = (_dMax - fitness) / _dMax * 100;
        }
        private void ShowDataImages(object sender, IndividualEventArgs e)
        {
            Dispatcher.Invoke(delegate
            {
                if (_tmpIndividual == null || _originalBitmap == null)
                {
                    return;
                }

                lock (_tmpIndividual)
                {
                    if (_bestOfAllIndividual == null)
                    {
                        _bestOfAllIndividual = _tmpIndividual.CloneIndividual();
                        _newBestIndividual   = true;
                    }

                    if (_bestOfAllIndividual.Adaptation < _tmpIndividual.Adaptation)
                    {
                        _bestOfAllIndividual = _tmpIndividual.CloneIndividual();
                        _newBestIndividual   = true;

                        dataChartList.Add(new ChartKeyValue()
                        {
                            Key = _bestOfAllIndividual.Generation, Value = _bestOfAllIndividual.Adaptation
                        });
                    }

                    _topGenerationIndividual = _tmpIndividual.CloneIndividual();
                }

                using (var bit = new Bitmap(_originalBitmap.Width, _originalBitmap.Height))
                {
                    this.actualGeneticImage.Source = null;
                    Graphics graphics      = Graphics.FromImage(bit);
                    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    ImageRenderer.DrawImage(_topGenerationIndividual, graphics);
                    bit.Save("topGenerationIndividual.png", ImageFormat.Png);

                    if (_newBestIndividual == true)
                    {
                        this.bestGeneticImage.Source = null;
                        bit.Save("topIndividual.png", ImageFormat.Png);
                    }
                }

                var bitmap = new BitmapImage();
                var stream = File.OpenRead("topGenerationIndividual.png");

                bitmap.BeginInit();
                bitmap.CacheOption  = BitmapCacheOption.OnLoad;
                bitmap.StreamSource = stream;
                bitmap.EndInit();
                stream.Close();
                stream.Dispose();

                _generation          = _topGenerationIndividual.Generation;
                _killedChilds        = AlgorithmInformation.KilledChilds;
                this._bestFitness    = Math.Round(_bestOfAllIndividual.Adaptation, 2);
                this._currentFitness = Math.Round(_topGenerationIndividual.Adaptation, 2);
                this._mutationChance = AlgorithmInformation.MutationChance;
                this._mutationType   = (int)AlgorithmInformation.MutationType;


                this.actualGeneticImage.Source   = bitmap;
                this.generation.Content          = "Generation: " + _topGenerationIndividual.Generation.ToString();
                this.currentFitness.Content      = "Current fitness: " + Math.Round(_topGenerationIndividual.Adaptation, 2).ToString() + "%";
                this.populationLabel.Content     = "Population: " + AlgorithmInformation.Population;
                this.eliteLabel.Content          = "Elite: " + AlgorithmInformation.Elite;
                this.mutationTypeLabel.Content   = "Mutation type: " + AlgorithmInformation.MutationType.ToString();
                this.mutationChanceLabel.Content = "Mutation chance: " + AlgorithmInformation.MutationChance.ToString() + "%";
                this.killedChildsLabel.Content   = "Killed childs: " + AlgorithmInformation.KilledChilds;

                _shapesAmount = (int)this.ShapesAmountSlider.Value;

                if (this.mutationDynamicRadio.IsChecked ?? false)
                {
                    this.dinamicallyMutationLabel.Content = "Dynamic mutation: YES";
                    this._dunamicMutation = 1;
                }
                else
                {
                    this.dinamicallyMutationLabel.Content = "Dynamic mutation: NO";
                    this._dunamicMutation = 0;
                }

                if (this.twoParentRadio.IsChecked ?? false)
                {
                    this.reproductionTypeLabel.Content = "Reproduction: Two-parents";
                }
                else
                {
                    this.reproductionTypeLabel.Content = "Reproduction: Single-parent";
                }


                if (_newBestIndividual == true)
                {
                    var bitmap1 = new BitmapImage();
                    var stream1 = File.OpenRead("topIndividual.png");

                    bitmap1.BeginInit();
                    bitmap1.CacheOption  = BitmapCacheOption.OnLoad;
                    bitmap1.StreamSource = stream1;
                    bitmap1.EndInit();
                    stream1.Close();
                    stream1.Dispose();

                    this.bestGeneticImage.Source = bitmap1;
                    this.bestFitness.Content     = "Best fitness: " + Math.Round(_bestOfAllIndividual.Adaptation, 2).ToString() + "%";



                    _newBestIndividual = false;
                }
            });
        }