using opencvsharp for rotation/deskewing an Image is not rotating correctly
TheRealKraytonian opened this issue · comments
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:
What did you intend to be?
original code: https://becominghuman.ai/how-to-automatically-deskew-straighten-a-text-image-using-opencv-a0c30aed83df
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.