protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
              this.CreateTabContainer("StromaDetection");
              this.TabContainer.Enabled = true;

              (new Button
              {
            Text = "execute cell core segmentation",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.DisplayedImage) return;
            ProcessResult result = null;
            var progressDialog = new ProgressDialog { Message = "executing cell core segmentation", ProgressBarStyle = ProgressBarStyle.Marquee, AllowCancel = false };
            progressDialog.BackgroundTask += () =>
            {
              var segmentation = new CellCoreSegmentation();
              var executionParams = new ProcessExecutionParams(this.DisplayedImage);
              result = segmentation.Execute(executionParams);
            };
            progressDialog.CenterToScreen();
            progressDialog.ShowDialog();
            this.SetLayers(result.Layers.ToArray());
              };

              (new Button
              {
            Text = "execute threshold segmentation",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.DisplayedImage) return;
            var m = new Map(this.DisplayedImage.Width, this.DisplayedImage.Height);
            using (var gp = new GrayscaleProcessor(this.DisplayedImage.Clone() as Bitmap, RgbToGrayscaleConversion.Mean))
            {
              for (var x = 0; x < this.DisplayedImage.Width; x++)
              {
            for (var y = 0; y < this.DisplayedImage.Height; y++)
            {
              m[x, y] = gp.GetPixel(x, y) < this.threshold.Value ? 1u : 0u;
            }
              }
            }
            var layer = new ConnectedComponentCollector().Execute(m);
            layer.Name = "threshold " + this.threshold.Value + " segmentation";
            var layers = this.GetLayers().ToList();
            layers.Add(layer);
            this.SetLayers(layers.ToArray());
              };

              this.threshold = new NumericUpDown
              {
            Parent = new GroupBox
            {
              Parent = this.TabContainer,
              Dock = DockStyle.Top,
              Text = "threshold",
              Height = 40
            },
            Dock = DockStyle.Fill,
            Minimum = 0,
            Maximum = 255,
            Increment = 16,
            Value = 128,
            DecimalPlaces = 0
              };

              (new Button
              {
            Text = "display edges",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.edges);
              };

              (new Button
              {
            Text = "execute edge detection",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.stainH || null == this.stainE) return;
            this.responseH = Filtering.ExecuteSobel(this.stainH);
            this.responseE = Filtering.ExecuteSobel(this.stainE);
            var substracted = new double[this.responseH.Size.Width, this.responseH.Size.Height];
            var substractedRange = new Range<double>();
            for (var x = 0; x < this.responseH.Size.Width; x++)
            {
              for (var y = 0; y < this.responseH.Size.Height; y++)
              {
            var value = Math.Max(0, this.responseE.Gradient[x, y] - this.responseH.Gradient[x, y]);
            substracted[x, y] = value;
            substractedRange.Add(value);
              }
            }
            this.nonMaximumSupression = Filtering.ExecuteNonMaximumSupression(substracted, this.responseE.Orientation);
            this.edges = Visualization.Visualize(this.nonMaximumSupression, Visualization.CreateColorizing(substractedRange.Maximum));
            this.SetDisplayedImage(this.edges);
              };

              (new Button
              {
            Text = "display haematoxylin",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.stainH);
              };

              (new Button {
            Text = "display eosin",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.stainE);
              };

              (new Button {
            Text = "display source",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.source);
              };

              (new Button {
            Text = "execute deconvolution",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.DisplayedImage) return;
            this.source = this.DisplayedImage;
            var gpE = new ColorDeconvolution().Get2ndStain(this.DisplayedImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
            gpE.Dispose();
            this.stainE = gpE.Bitmap;
            var gpH = new ColorDeconvolution().Get1stStain(this.DisplayedImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
            gpH.Dispose();
            this.stainH = gpH.Bitmap;
            this.SetDisplayedImage(this.stainE);
              };
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
              this.CreateTabContainer("StromaDetection2");
              this.TabContainer.Enabled = true;
              RConnector.BinPath = @"C:\Program Files\R\R-3.1.0\bin\x64\";

              (new Button {
            Text = "cluster by roundness",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.SelectedLayer) return;
            try { RConnector.Engine.Evaluate("library(\"mclust\")"); }
            catch { throw new Exception("try install mclust"); }
            var progressDialog = new ProgressDialog {
              Message = "extracting features",
              ProgressBarStyle = ProgressBarStyle.Marquee,
              AllowCancel = false
            };
            progressDialog.BackgroundTask += () =>
            {
              var matrix = RConnector.Engine.CreateNumericMatrix(this.SelectedLayer.Objects.Count, 1);
              for (var i = 0; i < this.SelectedLayer.Objects.Count; i++)
              {
            matrix[i, 0] = this.SelectedLayer.Objects[i].Features["AspectRatioOfBoundingEllipsoid"].Value;
              }
              var result = this.cluster(matrix);
              this.drawClusters(result.Item1, result.Item2);
            };
            progressDialog.CenterToScreen();
            progressDialog.ShowDialog();
            this.RefreshBuffer();
              };

              (new Button {
            Text = "cluster by position",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.SelectedLayer) return;
            try { RConnector.Engine.Evaluate("library(\"mclust\")"); }
            catch { throw new Exception("try install mclust"); }
            var progressDialog = new ProgressDialog {
              Message = "extracting features",
              ProgressBarStyle = ProgressBarStyle.Marquee,
              AllowCancel = false
            };
            progressDialog.BackgroundTask += () =>
            {
              var matrix = RConnector.Engine.CreateNumericMatrix(this.SelectedLayer.Objects.Count, 2);
              for (var i = 0; i < this.SelectedLayer.Objects.Count; i++)
              {
            var io = this.SelectedLayer.Objects[i];
            matrix[i, 0] = io.Features["CentroidX"].Value;
            matrix[i, 1] = io.Features["CentroidY"].Value;
              }
              var result = this.cluster(matrix);
              this.drawClusters(result.Item1, result.Item2);
            };
            progressDialog.CenterToScreen();
            progressDialog.ShowDialog();
            this.RefreshBuffer();
              };

              this.clusters = new NumericUpDown {
            Parent = new GroupBox {
              Parent = this.TabContainer,
              Dock = DockStyle.Top,
              Text = "clusters",
              Height = 40
            },
            Dock = DockStyle.Fill,
            Minimum = 0,
            Maximum = 20,
            Increment = 1,
            Value = 0,
            DecimalPlaces = 0
              };

              (new Button {
            Text = "extract features",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.SelectedLayer) return;
            var progressDialog = new ProgressDialog {
              Message = "extracting features",
              ProgressBarStyle = ProgressBarStyle.Marquee,
              AllowCancel = false
            };
            progressDialog.BackgroundTask += () =>
            {
              Centroid.ProcessLayer(this.SelectedLayer);
              foreach (var io in this.SelectedLayer.Objects)
              {
            var boundingEllipsoid = BoundingEllipsoid.FromContour(io.Contour);
            if (!io.Features.Contains("AngleOfBoundingEllipsoid")) io.Features.Add(new AngleOfBoundingEllipsoid(boundingEllipsoid));
            if (!io.Features.Contains("AspectRatioOfBoundingEllipsoid")) io.Features.Add(new AspectRatioOfBoundingEllipsoid(boundingEllipsoid));
              }
            };
            progressDialog.CenterToScreen();
            progressDialog.ShowDialog();
              };

              (new Button {
            Text = "execute cell core segmentation",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.DisplayedImage) return;
            ProcessResult result = null;
            var progressDialog = new ProgressDialog {
              Message = "executing cell core segmentation",
              ProgressBarStyle = ProgressBarStyle.Marquee,
              AllowCancel = false
            };
            progressDialog.BackgroundTask += () =>
            {
              var segmentation = new CellCoreSegmentation();
              var executionParams = new ProcessExecutionParams(this.DisplayedImage);
              result = segmentation.Execute(executionParams);
            };
            progressDialog.CenterToScreen();
            progressDialog.ShowDialog();
            this.SetLayers(result.Layers.ToArray());
              };
        }