Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using opencvsharp for rotation/deskewing an Image is not rotating correctly #1672

Open
TheRealKraytonian opened this issue May 23, 2024 · 1 comment

Comments

@TheRealKraytonian
Copy link

TheRealKraytonian commented May 23, 2024

Summary of your issue

using opencvsharp for rotation/deskewing an Image is not rotating correctly

Environment

OS Name Microsoft Windows 10 Pro
System SKU LENOVO_MT_20S0_BU_Think_FM_ThinkPad T14 Gen 1
Processor Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz, 2112 Mhz, 4 Core(s), 8 Logical
Total Virtual Memory 60.2 GB

What did you do when you faced the problem?

Played with the some values and given const datastructures

Example code:

 #region Rotation / Deskewing
        public static void RotationDeskewing(IFormFile file)
        {
            try
            {
                string outputPath = @"C:\Users\billionaire\Documents\Projects\name\backend\Test\rotation-deskewing.png";
                static float GetSkewAngle(Mat image)
                {
                    if (image == null)
                    {
                        Console.WriteLine($"Error: Failed to read image from .");
                        return 0;
                    }

                    Mat rotationDeskewingImage = new Mat(image.Size(), image.Depth(), image.Channels());
                    Mat gray = new Mat(image.Size(), image.Depth(), image.Channels());
                    Mat blur = new Mat(image.Size(), image.Depth(), image.Channels());
                    Mat thresh = new Mat(image.Size(), image.Depth(), image.Channels());

                    Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);
                    Cv2.GaussianBlur(gray, blur, new OpenCvSharp.Size(9, 9), 0);
                    Cv2.Threshold(blur, thresh, 200, 255, ThresholdTypes.Binary);

                    Mat dilate = new Mat(image.Size(), image.Depth(), image.Channels());
                    Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(30, 5));

                    Cv2.Dilate(thresh, dilate, kernel, iterations: 2);

                    Point[][] contours;
                    HierarchyIndex[] hierarchy;

                    Cv2.FindContours(dilate, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);

                    List<Point[]> sortedContours = contours.OrderByDescending(cnt => Cv2.ContourArea(cnt)).ToList();

                    foreach (var c in contours)
                    {
                        Rect rect = Cv2.BoundingRect(c);
                        int h = rect.Height;
                        int w = rect.Width;
                        int x = rect.X;
                        int y = rect.Y;
                        Cv2.Rectangle(image, new OpenCvSharp.Point(x, y), new OpenCvSharp.Point(x + w, y + h), Scalar.FromRgb(0, 255, 0), 2);
                    }


                    Point[] largestContour = contours[0];

                    Console.WriteLine(largestContour.Length);

                    RotatedRect minAreaRect = Cv2.MinAreaRect(largestContour);

                    Mat newImage = new Mat(image.Size(), image.Depth(), image.Channels());

                    // Cv2.ImWrite(outputPath, newImage);

                    float angle = minAreaRect.Angle;
                    if (angle < -45)
                    {
                        angle = 90 + angle;
                    }

                    return -angle;
                }

                static Mat RotateImage(Mat cvImage, float angle)
                {

                    Mat newImage = cvImage.Clone();

                    Size size = newImage.Size();
                    int width = size.Width;
                    int height = size.Height;


                    Point2f center = new Point2f(width / 2f, height / 2f);

                    Mat rotationMatrix = Cv2.GetRotationMatrix2D(center, angle, 1.0);


                    Cv2.WarpAffine(newImage, newImage, rotationMatrix, size, InterpolationFlags.Cubic, BorderTypes.Replicate);

                    return newImage;
                }

                Mat DeskewImage(IFormFile file)
                {

                    using (var ms = new MemoryStream())
                    {
                        file.CopyTo(ms);
                        byte[] fileBytes = ms.ToArray();

                        using (Mat image = Cv2.ImDecode(fileBytes, ImreadModes.Color))
                        {

                            float angle = GetSkewAngle(image); 


                            Mat deskewedImage = RotateImage(image, -angle);

                            return deskewedImage;
                        }
                    }
                }
                Mat fixedImage = DeskewImage(file);
                Cv2.ImWrite(outputPath, fixedImage);

                Console.WriteLine($"Image successfully Deskewed and saved to '{outputPath}'.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
        #endregion
        

Output:

rotation-deskewing

input

What did you intend to be?

original code: https://becominghuman.ai/how-to-automatically-deskew-straighten-a-text-image-using-opencv-a0c30aed83df

fixedImage

@JoanCharmant
Copy link

Since it's a multi-step algorithm I think you should investigate a bit more to find exactly which part is causing the problem.

  • Does it find the bounding box of the paragraph correctly?
  • Does it find the correct angle for that bounding box?
  • Does rotating by a known angle works correctly?

If the problem is in the wrapper you should be able to point to a specific function that gives an unexpected output from given inputs. Otherwise the problem could also be in your implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants