public static StatisticsResult GenerateStatistics(ManualContourDTO contour)
        {
            System.Drawing.Bitmap bitmap = OrthancConnection.GetBitmapByInstanceId(contour.dicomid);
            int width  = bitmap.Width;
            int height = bitmap.Height;

            int[,] matrixWithContour = CannyAlgorithm.MakeMatrixFromPoints(width, height, contour.lines.First().points);

            int count = 0;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (matrixWithContour[x, y] == 0)
                    {
                        count++;
                    }
                }
            }

            int[,] image = CannyAlgorithm.ReadMatrixFromBitmap(bitmap);


            double pixelSizeX = 0;
            double pixelSizeY = 0;

            List <string> splitString = contour.pixelSpacing.Split('\\').ToList();
            List <double> split       = new List <double>();

            foreach (var s in splitString)
            {
                double d = 0;
                if (double.TryParse(s, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out d))
                {
                    split.Add(d);
                }
            }
            if (split.Count >= 2)
            {
                pixelSizeX = split[0];
                pixelSizeY = split[1];
            }

            double pixelAreaInMms   = pixelSizeX * pixelSizeY;
            double pixelLenghtInMms = pixelSizeX;

            return(GenerateStatistics(contour.lines.First().points, matrixWithContour, image, 0, width, 0, height, pixelAreaInMms, pixelLenghtInMms, contour.centralPoints.First()));
        }
        public static List <Point> CannyWithoutStatistics(string dicomId, List <Point> points, int canvasWidth, int canvasHeight)
        {
            System.Drawing.Bitmap             bitmap  = OrthancConnection.GetBitmapByInstanceId(dicomId);
            System.Drawing.Rectangle          rect    = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
            IntPtr ptr   = bmpData.Scan0;
            int    bytes = Math.Abs(bmpData.Stride) * bitmap.Height;

            byte[] rgbValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

            double[, ][] sobel;
            int          width, height;

            width  = bitmap.Width;
            height = bitmap.Height;

            int xmin, xmax, ymin, ymax;

            (xmin, xmax, ymin, ymax) = FindPointsMinMaxPositions(points, width, height);

            sobel = SobelOperator(rgbValues, xmin, xmax, ymin, ymax, bmpData.Stride);
            bitmap.UnlockBits(bmpData);

            double[, ][] gradient = FindIntensityGradient(sobel, xmin, xmax, ymin, ymax);
            double[,] edges = NonMaximumSuppression(gradient, xmin, xmax, ymin, ymax);
            int[] distribution = DistributionFunction(edges, xmin, xmax, ymin, ymax);
            distribution = CumulativeDistributionFunction(distribution);

            int    min, max;
            double lowerThreshold = 0.70, higherThreshold = 0.95;

            (min, max)          = ChooseThreshold(distribution, lowerThreshold, higherThreshold);
            int[,] foundedEdges = HysteresisThreshold(edges, xmin, xmax, ymin, ymax, min, max);

            int[,] foundedEdges2 = Make4ConnectedMatrix(foundedEdges, xmin, xmax, ymin, ymax);

            double       weight = 2.5;
            List <Point> pixels = new List <Point>(Graph.FindShortestPath(foundedEdges2, xmin, xmax, ymin, ymax, weight, points));

            return(pixels);
        }
        public static SemiAutomaticContourDTO TrivialContour(SemiAutomaticPointsDTO points)
        {
            List <Point> pixels = new List <Point>();
            int          count  = points.lines.First().points.Count;

            for (int i = 0; i < points.lines.First().points.Count; i++)
            {
                int          x1 = points.lines.First().points[i].x;
                int          y1 = points.lines.First().points[i].y;
                int          x2 = points.lines.First().points[(i + 1) % count].x;
                int          y2 = points.lines.First().points[(i + 1) % count].y;
                List <Point> pixelsBresenham = new List <Point>();
                BresenhamClass.Bresenham(pixelsBresenham, x1, y1, x2, y2);
                pixels = pixels.Concat(pixelsBresenham).ToList();
            }

            List <LinePointsAndPixels> lines = new List <LinePointsAndPixels>();
            LinePointsAndPixels        line  = new LinePointsAndPixels();

            line.points     = new List <Point>(points.lines.First().points);
            line.pixels     = new List <Point>(pixels);
            line.brushColor = points.lines.First().brushColor;

            lines.Add(line);

            System.Drawing.Bitmap bitmap = OrthancConnection.GetBitmapByInstanceId(points.dicomid);
            int[,] matrixWithContour = CannyAlgorithm.MakeMatrixFromPoints(bitmap.Width, bitmap.Height, pixels);
            int[,] image             = CannyAlgorithm.ReadMatrixFromBitmap(bitmap);

            StatisticsResult statisticsResult = Statistics.GenerateStatistics(pixels, matrixWithContour, image, 0, bitmap.Width, 0, bitmap.Height,
                                                                              0, 0, points.centralPoints.First());

            SemiAutomaticContourDTO contour = new SemiAutomaticContourDTO(points.guid,
                                                                          points.dicomid, points.tag, lines, points.width, points.height, statisticsResult, points.centralPoints, points.pixelSpacing);

            return(contour);
        }
        public static (List <Point>, StatisticsResult) Canny(string dicomId, List <Point> points, int canvasWidth, int canvasHeight,
                                                             List <Point> centralPoints, string pixelSpacing)
        {
            System.Drawing.Bitmap             bitmap  = OrthancConnection.GetBitmapByInstanceId(dicomId);
            System.Drawing.Rectangle          rect    = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
            IntPtr ptr   = bmpData.Scan0;
            int    bytes = Math.Abs(bmpData.Stride) * bitmap.Height;

            byte[] rgbValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

            double[, ][] sobel;
            int          width, height;

            width  = bitmap.Width;
            height = bitmap.Height;

            int xmin, xmax, ymin, ymax;

            (xmin, xmax, ymin, ymax) = FindPointsMinMaxPositions(points, width, height);

            sobel = SobelOperator(rgbValues, xmin, xmax, ymin, ymax, bmpData.Stride);
            bitmap.UnlockBits(bmpData);

            double[, ][] gradient = FindIntensityGradient(sobel, xmin, xmax, ymin, ymax);
            double[,] edges = NonMaximumSuppression(gradient, xmin, xmax, ymin, ymax);
            int[] distribution = DistributionFunction(edges, xmin, xmax, ymin, ymax);
            distribution = CumulativeDistributionFunction(distribution);

            int    min, max;
            double lowerThreshold = 0.70, higherThreshold = 0.95;

            (min, max)          = ChooseThreshold(distribution, lowerThreshold, higherThreshold);
            int[,] foundedEdges = HysteresisThreshold(edges, xmin, xmax, ymin, ymax, min, max);

            int[,] foundedEdges2 = Make4ConnectedMatrix(foundedEdges, xmin, xmax, ymin, ymax);

            double       weight = 2.5;
            List <Point> pixels = new List <Point>(Graph.FindShortestPath(foundedEdges2, xmin, xmax, ymin, ymax, weight, points));

            int[,] matrixWithContour = MakeMatrixFromPoints(width, height, pixels);
            int[,] matrix4Connected  = Make4ConnectedMatrix(matrixWithContour, 0, 0, width, height);
            List <Point> shortestPixels = new List <Point>(MakePointsFromMatrix(width, height, matrix4Connected));

            int[,] image = ReadMatrixFromBitmap(bitmap);

            StatisticsResult statisticsResult = null;

            double pixelSizeX = 0;
            double pixelSizeY = 0;

            if (pixelSpacing != null)
            {
                List <string> splitString = pixelSpacing.Split('\\').ToList();
                List <double> split       = new List <double>();
                foreach (var s in splitString)
                {
                    double d = 0;
                    if (double.TryParse(s, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out d))
                    {
                        split.Add(d);
                    }
                }
                if (split.Count >= 2)
                {
                    pixelSizeX = split[0];
                    pixelSizeY = split[1];
                }
            }

            double pixelAreaInMms   = pixelSizeX * pixelSizeY;
            double pixelLenghtInMms = pixelSizeX;

            statisticsResult = Statistics.GenerateStatistics(shortestPixels, matrixWithContour, image, 0, width, 0, height, pixelAreaInMms, pixelLenghtInMms, centralPoints.First());

            return(shortestPixels, statisticsResult);
        }