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); } }
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 }