예제 #1
0
        public void GetPaperFromImageTest()
        {
            foreach (string image in Images)
            {
                //Gets rectangles
                Point[][] rectangles = OpenCVWrapper.IdentifyRectangles($"Images//{image}.jpg");
                //Checks valid json was output
                Assert.IsNotNull(rectangles);
                //Checks at least 1 rectangle was identified
                Assert.AreNotEqual(rectangles.Length, 0);

                Bitmap bitmap = new Bitmap($"Images//{image}.jpg");
                //Get rectangle that corresponds to the paper (I hope)
                Point[] paper = bitmap.IdentifyPaperCorners(rectangles);
                Assert.IsNotNull(paper);

                //Draws all points on the image for manual checking
                Bitmap tempBitmap = new Bitmap(bitmap);
                foreach (Point corner in paper)
                {
                    for (int xOff = -2; xOff < 3; xOff++)
                    {
                        for (int yOff = -2; yOff < 3; yOff++)
                        {
                            if (corner.X + xOff < tempBitmap.Width && corner.Y + yOff < tempBitmap.Height &&
                                corner.X + xOff >= 0 &&
                                corner.Y + yOff >= 0)
                            {
                                tempBitmap.SetPixel(corner.X + xOff, corner.Y + yOff, Color.Red);
                            }
                        }
                    }
                }

                //Save modified image
                if (!Directory.Exists($"Images/Out/{image}"))
                {
                    Directory.CreateDirectory($"Images/Out/{image}");
                }
                tempBitmap.Save($"Images/Out/{image}/1 corners.png", ImageFormat.Png);

                //Transforms and saves image for manual checking
                bitmap = bitmap.PerspectiveTransformImage(paper, 1414, 1000);
                bitmap.Save($"Images/Out/{image}/2 transform.png", ImageFormat.Png);
            }
        }
예제 #2
0
        public IActionResult Create(IFormCollection form)
        {
            //Start of working directory
            string workingDirectory = Path.Combine(_workingDirectory, "Working ");
            // ReSharper disable once RedundantAssignment, needs to be there for non debug compile
            Bitmap initialImage = null;

#if !DEBUG
            try
            {
#endif

            #region Setup

            //Checks there is a file
            if (form.Files.Count == 0)
            {
                return(new BadRequestResult());
            }

            //Gets the id for this upload, locked so only one thread can enter at a time
            int id = SetupId(ref workingDirectory);
            //Cleans up Working folders that are leftover for some reason on every 20th pass
            if (id % 20 == 0)
            {
                Thread cleanWorkingDirectories = new Thread(CleanWorkingDirectories);
                cleanWorkingDirectories.Start();
            }
            //Saves the file sent and get if transformation is needed
            bool transform = ProcessFormData(form, workingDirectory);
            //Tries to load file sent as image and will return an UnsupportedMediaTypeResult if file can't be loaded to a bitmap
            try
            {
                //Tries to load the image
                initialImage = LoadImage(form, workingDirectory);
            }
            catch (Exception)
            {
                Directory.Delete(workingDirectory, true);
                return(new UnsupportedMediaTypeResult());
            }

            #endregion

            #region Image Manipulation

            //Scales image to be less than a certain number of pixels
            Bitmap scaledImage = ScaleImage(workingDirectory, initialImage, transform);
            Bitmap perspectiveImage;
            //Will only run this if transform flag has been checked
            if (transform)
            {
                //Finds possible rectangles with OpenCV
                Point[][] rectangles =
                    OpenCVWrapper.IdentifyRectangles($"\"{Path.Combine(workingDirectory, "scaled.png")}\"");
                if (rectangles == null || rectangles.Length == 0)
                {
                    initialImage.Dispose();
                    Directory.Delete(workingDirectory, true);
                    return(new StatusCodeResult((int)HttpStatusCode.InternalServerError));
                }

#if DEBUG
                Bitmap temp = Debug.DrawPoints(scaledImage, rectangles);
                temp.Save(Path.Combine(_workingDirectory, "Debug", "3 Rectangles.png"), ImageFormat.Png);
#endif

                //Finds the correct rectangle
                Point[] paper = scaledImage.IdentifyPaperCorners(rectangles);
                if (paper == null || paper.Length != 4)
                {
                    initialImage.Dispose();
                    Directory.Delete(workingDirectory, true);
                    return(new StatusCodeResult((int)HttpStatusCode.InternalServerError));
                }

#if DEBUG
                temp = Debug.DrawPoints(scaledImage, paper);
                temp.Save(Path.Combine(_workingDirectory, "Debug", "4 Paper.png"), ImageFormat.Png);
#endif

                perspectiveImage = TransformImage(scaledImage, paper);
            }
            else
            {
                perspectiveImage = scaledImage;
            }

            #endregion

            #region Color Identification

            //Gets threshold array for image
            bool[][] threshold = CreateThresholds(perspectiveImage);
            //Thins lines
            ThinLines(threshold);

            #endregion

            #region Line Identification

            //Finds lines
            List <List <PointF> > lineParts = threshold.CreateLineParts();
            //Reduces number of points in lines
            lineParts.ReduceLines();
            //Finds loops
            List <List <PointF> > loops = lineParts.CreateLoops();
            //Joins remaining lines
            lineParts.ConnectLines();
            //Create line objects
            List <Line> lines = LineCreation.CreateLineObjects(lineParts, loops, perspectiveImage);

            #endregion

            #region Map Creation

            //Creates a map
            Map map = new Map
            {
                Id    = id,
                Lines = lines,
                Ratio = (double)perspectiveImage.Width / perspectiveImage.Height
            };

            //Converts map to json
            string json = JsonConvert.SerializeObject(map).Replace("\"IsEmpty\":false,", "");

            SaveMap(id, json);

            #endregion

            initialImage.Dispose();
            Directory.Delete(workingDirectory, true);

            //Returns map
            return(new ObjectResult(json)
            {
                //Sets the media type to be json instead of string
                ContentTypes = new MediaTypeCollection
                {
                    "application/json",
                    "charset=utf-8"
                }
            });

#if !DEBUG
        }

        catch
        {
            initialImage?.Dispose();
            if (Directory.Exists(workingDirectory))
            {
                Directory.Delete(workingDirectory, true);
            }
            return(new StatusCodeResult((int)HttpStatusCode.InternalServerError));
        }
#endif
        }