static void Main(string[] args)
        {
            #region init
              if (0 == args.Length)
              {
            Console.WriteLine("no slide name");
            return;
              }
              var slideName = args[0];
              var processinHelper = new Processing(slideName);
              var slide = processinHelper.Slide;
              #endregion init

              var part = new WsiPartitioner(new Rectangle(new Point(0, 0), slide.Size), new Size(1000, 1000), new Size(0, 0), 1.0);
              var tissueData = new TiledProcessInformation<bool>(part, slideName);

              #region global tissue detection
              int overviewImageWidth = slide.Size.Width / OverviewTileSize;
              int overviewImageHeight = slide.Size.Height / OverviewTileSize;

              Bitmap overviewImage = slide.GetImagePart(0, 0, slide.Size.Width, slide.Size.Height, overviewImageWidth, overviewImageHeight);

              var bitmapProcessor = new BitmapProcessor(overviewImage);

              ObjectLayer overviewLayer = new TissueDetector().Execute(bitmapProcessor, Radius, NoiseLevel);

              bitmapProcessor.Dispose();

              DrawObjectsToImage(overviewImage, overviewLayer, Color.Black);
              overviewImage.Save(processinHelper.DataPath + "tissueDetectionOverview.png");
              #endregion global tissue detection

              //part.Tiles[]
              foreach (var tile in part)
              {
            #region global tissue detection
            var rect = tile.SourceRect;
            int overviewX = rect.X / OverviewTileSize;
            int overviewY = rect.Y / OverviewTileSize;
            int windowSize = rect.Width / OverviewTileSize;

            bool tileInObject = true;
            int partsOutside = 0;

            for (int y = 0; y < windowSize; y++)
            {
              for (int x = 0; x < windowSize; x++)
              {
            int newX = overviewX + x;
            int newY = overviewY + y;

            if (newX < 0 || newX >= overviewLayer.Map.Width || newY < 0 || newY >= overviewLayer.Map.Height) { continue; }

            uint id = overviewLayer.Map[newX, newY];
            if (id != 0) continue;
            partsOutside++;
            if (!(partsOutside >= Math.Pow(windowSize + 1, 2) * 0.75)) continue;
            tileInObject = false;
            break;
              }
              if (!tileInObject) { break; }
            }
            tissueData.AddDataToCurrentTile(tileInObject);
            #endregion global tissue detection
            if (tileInObject) Console.WriteLine(tile.SourceRect + ":" + partsOutside);
              }
              tissueData.ToFile(processinHelper.DataPath + "tissueData.tpi");
              using (Bitmap b = tissueData.GenerateHeatMap(tissue => tissue ? Color.Green : Color.Red))
            b.Save(processinHelper.DataPath + "tissueData.png");

              Console.WriteLine("done");
              Console.ReadKey();
        }
        private static void Main(string[] args)
        {
            #region init
              if (0 == args.Length)
              {
            Console.WriteLine("no slide name");
            return;
              }
              var slideName = args[0];
              var processinHelper = new Processing(slideName);
              var slide = processinHelper.Slide;
              #endregion init

              TiledProcessInformation<uint[]> haematoxylinHistogram;
              TiledProcessInformation<uint[]> eosinHistogram;

              if (!File.Exists(processinHelper.DataPath + "haematoxylinHistogram.tpi") || !File.Exists(processinHelper.DataPath + "eosinHistogram.tpi"))
              {
            if (!Directory.Exists(processinHelper.DataPath + "deconvolution")) Directory.CreateDirectory(processinHelper.DataPath + "deconvolution");
            var tissueData = TiledProcessInformation<bool>.FromFile(processinHelper.DataPath + "tissueData.tpi");
            haematoxylinHistogram = new TiledProcessInformation<uint[]>(tissueData.Partitioner, tissueData.WsiUri);
            eosinHistogram = new TiledProcessInformation<uint[]>(tissueData.Partitioner, tissueData.WsiUri);
            var partitioner = tissueData.Partitioner;
            var dict = new Dictionary<Point, WsiRect>();
            foreach (var tile in tissueData.Partitioner)
              dict.Add(tissueData.Partitioner.CurrentIndices, tile);
            var stopwatch = new Stopwatch();
            foreach (var tile in partitioner)
            {
              var tissueTile = dict[partitioner.CurrentIndices];
              if (!tissueData[tissueTile]) continue;
              stopwatch.Start();
              using (var tileImage = slide.GetImagePart(tile))
              {
            var hHistogramValue = new uint[256];
            var hValues = new List<double>();
            using (var gpH = new ColorDeconvolution().Get1stStain(tileImage, ColorDeconvolution.KnownStain.HaematoxylinEosin))
            {
              foreach (var intensity in gpH.GetPixels())
              {
                hHistogramValue[intensity]++;
                hValues.Add(intensity);
              }
              haematoxylinHistogram.AddDataToCurrentTile(hHistogramValue);
              gpH.Dispose();
              gpH.Bitmap.Save(processinHelper.DataPath + "deconvolution\\" + partitioner.CurrentIndices + ".h.png");
            }
            var eHistogramValue = new uint[256];
            var eValues = new List<double>();
            using (var gpE = new ColorDeconvolution().Get2ndStain(tileImage, ColorDeconvolution.KnownStain.HaematoxylinEosin))
            {
              foreach (var intensity in gpE.GetPixels())
              {
                eHistogramValue[intensity]++;
                eValues.Add(intensity);
              }
              eosinHistogram.AddDataToCurrentTile(eHistogramValue);
              gpE.Dispose();
              gpE.Bitmap.Save(processinHelper.DataPath + "deconvolution\\" + partitioner.CurrentIndices + ".e.png");
            }
            NumericVector hHistogram = RConnector.Engine.CreateNumericVector(hValues);
            RConnector.Engine.SetSymbol("hHistogram", hHistogram);
            NumericVector eHistogram = RConnector.Engine.CreateNumericVector(eValues);
            RConnector.Engine.SetSymbol("eHistogram", eHistogram);
            var handle = RConnector.StartOutput();
            RConnector.Engine.Evaluate("hist(eHistogram, col=rgb(1,0,0,0.5),xlim=c(0,255), main=\"" + partitioner.CurrentIndices + "\", xlab=\"HE\")");
            RConnector.Engine.Evaluate("hist(hHistogram, col=rgb(0,0,1,0.5), add=T)");
            var output = RConnector.EndOutput(handle);
            output.Save(processinHelper.DataPath + "deconvolution\\histogram" + partitioner.CurrentIndices + ".png");
              }
              stopwatch.Stop();
              Console.WriteLine(partitioner.CurrentIndices + ":" + (stopwatch.ElapsedMilliseconds / 1000d) + "s");
              stopwatch.Reset();
            }
            haematoxylinHistogram.ToFile(processinHelper.DataPath + "haematoxylinHistogram.tpi");
            eosinHistogram.ToFile(processinHelper.DataPath + "eosinHistogram.tpi");
              }
              else
              {
            haematoxylinHistogram = TiledProcessInformation<uint[]>.FromFile(processinHelper.DataPath + "haematoxylinHistogram.tpi");
            eosinHistogram = TiledProcessInformation<uint[]>.FromFile(processinHelper.DataPath + "eosinHistogram.tpi");
              }

              var hRange = new Range<uint>();
              foreach (var tile in haematoxylinHistogram.Partitioner)
              {
            if (null == haematoxylinHistogram[tile]) continue;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += haematoxylinHistogram[tile][i] * (255 - i);
            }
            hRange.Add(sum);
              }
              Func<uint[], Color> h2pixel = h =>
              {
            if (null == h) return Color.Gray;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += h[i] * (255 - i);
            }
            var ratio = (double)sum / hRange.Maximum;
            return Color.FromArgb(0, 0, (int)Math.Round(255.0 * ratio));
              };
              var eRange = new Range<uint>();
              foreach (var tile in eosinHistogram.Partitioner)
              {
            if (null == eosinHistogram[tile]) continue;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += eosinHistogram[tile][i] * (255 - i);
            }
            eRange.Add(sum);
              }
              Func<uint[], Color> e2pixel = e =>
              {
            if (null == e) return Color.Gray;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += e[i] * (255 - i);
            }
            var ratio = (double)sum / eRange.Maximum;
            return Color.FromArgb((int)Math.Round(255.0 * ratio), 0, 0);
              };
              using (Bitmap b = haematoxylinHistogram.GenerateHeatMap(h2pixel))
            b.Save(processinHelper.DataPath + "haematoxylinHistogram.png");
              using (Bitmap b = eosinHistogram.GenerateHeatMap(e2pixel))
            b.Save(processinHelper.DataPath + "eosinHistogram.png");
              Console.WriteLine("done");
              Console.ReadKey();
        }