private static void PrintColorModels()
        {
            ObjectBackgroundColorModels colorModels = ObjectBackgroundColorModels.LoadFromFile(@"./gmm_3.clr");

            PrintGMM("OBJECT COLOR", (GaussianMixtureColorModel)colorModels.ObjectColorModel);
            PrintGMM("BACKGROUND COLOR", (GaussianMixtureColorModel)colorModels.BackgroundColorModel);
        }
        private void OnLoadColorModelButtonClick(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog();

            openDialog.Filter           = "Color models|*.clr";
            openDialog.RestoreDirectory = true;
            bool?result = openDialog.ShowDialog();

            if (result != true)
            {
                return;
            }

            this.colorModels = ObjectBackgroundColorModels.LoadFromFile(openDialog.FileName);

            this.UpdateControlsAccordingToCurrentState();
        }
        private void OnLearnColorModelButtonClick(object sender, RoutedEventArgs e)
        {
            if (this.backgroundImagesListBox.SelectedIndex != -1)
            {
                ImageInfo currentImageInfo = this.imageInfos[this.backgroundImagesListBox.SelectedIndex];
                currentImageInfo.ColorModelMask = this.colorMaskEditor.GetMask(currentImageInfo.Image.PixelWidth, currentImageInfo.Image.PixelHeight);
            }

            List <Color> objectColors     = new List <Color>();
            List <Color> backgroundColors = new List <Color>();

            for (int i = 0; i < this.imageInfos.Count; ++i)
            {
                if (this.imageInfos[i].ColorModelMask == null)
                {
                    continue;
                }

                Image2D <Color> image = ImageHelper.BitmapSourceToImage2D(this.imageInfos[i].Image);
                ExtractObjectBackgroundColorsByMask(
                    image,
                    this.imageInfos[i].ColorModelMask,
                    objectColors,
                    backgroundColors);

                Image2D.SaveToFile(image, string.Format("image_{0}.png", i));
                Image2D.SaveToFile(this.imageInfos[i].ColorModelMask, string.Format("mask_{0}.png", i));
            }

            if (objectColors.Count == 0)
            {
                MessageBox.Show("No object pixels specified.");
                return;
            }

            if (backgroundColors.Count == 0)
            {
                MessageBox.Show("No background pixels specified.");
                return;
            }

            Helper.Subsample(objectColors, this.algorithmProperties.MaxPixelsToLearnFrom);
            Helper.Subsample(backgroundColors, this.algorithmProperties.MaxPixelsToLearnFrom);

            try
            {
                GaussianMixtureColorModel objectModel = GaussianMixtureColorModel.Fit(
                    objectColors.Take(this.algorithmProperties.MaxPixelsToLearnFrom),
                    this.algorithmProperties.MixtureComponentCount,
                    this.algorithmProperties.StopTolerance);
                GaussianMixtureColorModel backgroundModel = GaussianMixtureColorModel.Fit(
                    backgroundColors.Take(this.algorithmProperties.MaxPixelsToLearnFrom),
                    this.algorithmProperties.MixtureComponentCount,
                    this.algorithmProperties.StopTolerance);
                this.colorModels = new ObjectBackgroundColorModels(objectModel, backgroundModel);

                this.UpdateControlsAccordingToCurrentState();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void DoSegmentation(object sender, DoWorkEventArgs e)
        {
            Random.SetSeed(666);

            // Load and downscale image
            Image2D <Color> originalImage   = Image2D.LoadFromFile(this.segmentationProperties.ImageToSegment);
            double          scale           = this.segmentationProperties.DownscaledImageSize / (double)Math.Max(originalImage.Width, originalImage.Height);
            Image2D <Color> downscaledImage = Image2D.LoadFromFile(this.segmentationProperties.ImageToSegment, scale);

            this.segmentedImage = Image2D.ToRegularImage(downscaledImage);

            // Load color models
            ObjectBackgroundColorModels colorModels = ObjectBackgroundColorModels.LoadFromFile(this.segmentationProperties.ColorModel);

            // Setup shape model
            ShapeModel model = ShapeModel.LoadFromFile(this.segmentationProperties.ShapeModel);

            this.segmentator.ShapeModel = model;

            // Common settings
            segmentator.ObjectColorUnaryTermWeight        = this.segmentationProperties.ObjectColorUnaryTermWeight;
            segmentator.BackgroundColorUnaryTermWeight    = this.segmentationProperties.BackgroundColorUnaryTermWeight;
            segmentator.ObjectShapeUnaryTermWeight        = this.segmentationProperties.ObjectShapeUnaryTermWeight;
            segmentator.BackgroundShapeUnaryTermWeight    = this.segmentationProperties.BackgroundShapeUnaryTermWeight;
            segmentator.ColorDifferencePairwiseTermWeight = this.segmentationProperties.ColorDifferencePairwiseTermWeight;
            segmentator.ColorDifferencePairwiseTermCutoff = this.segmentationProperties.ColorDifferencePairwiseTermCutoff;
            segmentator.ConstantPairwiseTermWeight        = this.segmentationProperties.ConstantPairwiseTermWeight;
            segmentator.ShapeEnergyWeight = this.segmentationProperties.ShapeEnergyWeight;

            // Custom setup
            if (this.segmentator is BranchAndBoundSegmentationAlgorithm)
            {
                this.SetupBranchAndBoundSegmentationAlgorithm((BranchAndBoundSegmentationAlgorithm)this.segmentator);
            }
            else if (this.segmentator is CoordinateDescentSegmentationAlgorithm)
            {
                this.SetupCoordinateDescentSegmentationAlgorithm((CoordinateDescentSegmentationAlgorithm)this.segmentator);
            }
            else if (this.segmentator is AnnealingSegmentationAlgorithm)
            {
                this.SetupAnnealingSegmentationAlgorithm((AnnealingSegmentationAlgorithm)this.segmentator);
            }
            else if (this.segmentator is SimpleSegmentationAlgorithm)
            {
                this.SetupSimpleSegmentationAlgorithm((SimpleSegmentationAlgorithm)this.segmentator);
            }

            // Show original image in status window)
            this.currentImage.Image = (Image)this.segmentedImage.Clone();

            // Run segmentation
            SegmentationSolution solution = segmentator.SegmentImage(downscaledImage, colorModels);

            // Re-run B&B segmentation with reduced constraints in two-step mode
            if (this.segmentator is BranchAndBoundSegmentationAlgorithm && this.segmentationProperties.UseTwoStepApproach && !this.segmentator.WasStopped)
            {
                BranchAndBoundSegmentationAlgorithm branchAndBoundSegmentator =
                    (BranchAndBoundSegmentationAlgorithm)this.segmentator;

                branchAndBoundSegmentator.MaxCoordFreedom  = this.segmentationProperties.MaxCoordFreedom;
                branchAndBoundSegmentator.MaxWidthFreedom  = this.segmentationProperties.MaxWidthFreedom;
                branchAndBoundSegmentator.StartConstraints = this.bestConstraints;
                branchAndBoundSegmentator.ShapeEnergyLowerBoundCalculator = new ShapeEnergyLowerBoundCalculator(
                    this.segmentationProperties.LengthGridSize, this.segmentationProperties.AngleGridSize);

                Console.WriteLine("Performing second pass...");
                solution = segmentator.SegmentImage(downscaledImage, colorModels);
            }

            // Save mask as worker result
            e.Result = solution;
        }
        private void OnLearnColorModelButtonClick(object sender, RoutedEventArgs e)
        {
            if (this.backgroundImagesListBox.SelectedIndex != -1)
            {
                ImageInfo currentImageInfo = this.imageInfos[this.backgroundImagesListBox.SelectedIndex];
                currentImageInfo.ColorModelMask = this.colorMaskEditor.GetMask(currentImageInfo.Image.PixelWidth, currentImageInfo.Image.PixelHeight);
            }

            List<Color> objectColors = new List<Color>();
            List<Color> backgroundColors = new List<Color>();
            for (int i = 0; i < this.imageInfos.Count; ++i)
            {
                if (this.imageInfos[i].ColorModelMask == null)
                    continue;

                Image2D<Color> image = ImageHelper.BitmapSourceToImage2D(this.imageInfos[i].Image);
                ExtractObjectBackgroundColorsByMask(
                    image,
                    this.imageInfos[i].ColorModelMask,
                    objectColors,
                    backgroundColors);

                Image2D.SaveToFile(image, string.Format("image_{0}.png", i));
                Image2D.SaveToFile(this.imageInfos[i].ColorModelMask, string.Format("mask_{0}.png", i));
            }

            if (objectColors.Count == 0)
            {
                MessageBox.Show("No object pixels specified.");
                return;
            }

            if (backgroundColors.Count == 0)
            {
                MessageBox.Show("No background pixels specified.");
                return;
            }

            Helper.Subsample(objectColors, this.algorithmProperties.MaxPixelsToLearnFrom);
            Helper.Subsample(backgroundColors, this.algorithmProperties.MaxPixelsToLearnFrom);

            try
            {
                GaussianMixtureColorModel objectModel = GaussianMixtureColorModel.Fit(
                objectColors.Take(this.algorithmProperties.MaxPixelsToLearnFrom),
                this.algorithmProperties.MixtureComponentCount,
                this.algorithmProperties.StopTolerance);
                GaussianMixtureColorModel backgroundModel = GaussianMixtureColorModel.Fit(
                    backgroundColors.Take(this.algorithmProperties.MaxPixelsToLearnFrom),
                    this.algorithmProperties.MixtureComponentCount,
                    this.algorithmProperties.StopTolerance);
                this.colorModels = new ObjectBackgroundColorModels(objectModel, backgroundModel);

                this.UpdateControlsAccordingToCurrentState();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void OnLoadColorModelButtonClick(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog();
            openDialog.Filter = "Color models|*.clr";
            openDialog.RestoreDirectory = true;
            bool? result = openDialog.ShowDialog();
            if (result != true)
                return;

            this.colorModels = ObjectBackgroundColorModels.LoadFromFile(openDialog.FileName);

            this.UpdateControlsAccordingToCurrentState();
        }