opencvsharp
opencvsharp copied to clipboard
Need Help for Warpping and Deskewing
Summary of your issue
I would like to fix word of text before scanning via Tesseract with OpenCvSharp. Code's snippet and images's results as following. I can not find warpping and deskewing image. Thank you in advance for your effort.
Example code:
private Mat warp(Mat sourceImage)
{
var copySourceImage = new Mat();
var colorSourceImage = new Mat();
sourceImage.CopyTo(copySourceImage);
sourceImage.CopyTo(colorSourceImage);
Cv2.CvtColor(colorSourceImage, colorSourceImage, ColorConversionCodes.GRAY2RGB);
var blurImage = new Mat();
Cv2.GaussianBlur(copySourceImage, blurImage, new OpenCvSharp.Size(7, 7), 1);
showMat(copySourceImage, "warp > blurImage", true);
var grayInput = CreateGrayImage(blurImage);
var cannyImage = new Mat();
Cv2.Canny(grayInput, cannyImage, threshold1: 0, threshold2: 255);
showMat(cannyImage, "warp > cannyImage", true);
var dilateRectKernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Mat dilate = new Mat();
Cv2.Dilate(cannyImage, dilate, dilateRectKernel, iterations: 4);
showMat(dilate, "warp > dilate", true);
Mat erode = new Mat();
Cv2.Erode(dilate, erode, null, iterations: 1);
showMat(erode, "warp > erode", true);
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchyIndexes;
Cv2.FindContours(
dilate,
out contours,
out hierarchyIndexes,
mode: RetrievalModes.External,
method: ContourApproximationModes.ApproxNone);
if (contours.Length == 0)
{
throw new NotSupportedException("Couldn't find any object in the image.");
}
var orderedContours = contours.OrderByDescending(c => Cv2.ContourArea(c)).ToArray();
// Find largest contour and surround in min area box
var paperContour = orderedContours[0].ToList();
var peri = Cv2.ArcLength(paperContour, true);
var approx = Cv2.ApproxPolyDP(paperContour, 0.02 * peri, true).ToList();
List<OpenCvSharp.Point2f> approx2 = new List<OpenCvSharp.Point2f>();
List<OpenCvSharp.Point2f> paperContour2 = new List<OpenCvSharp.Point2f>();
List<List<OpenCvSharp.Point>> paperContourPoints = new List<List<OpenCvSharp.Point>>() { { paperContour } };
List<List<OpenCvSharp.Point>> paperApproxPoints = new List<List<OpenCvSharp.Point>>() { { approx } };
Cv2.DrawContours(colorSourceImage, paperContourPoints, -1, Scalar.LimeGreen, 1, LineTypes.AntiAlias);
Cv2.DrawContours(colorSourceImage, paperApproxPoints, -1, Scalar.Red, 1, LineTypes.AntiAlias);
Cv2.Rectangle(colorSourceImage, Cv2.BoundingRect(approx), Scalar.Blue, 1, LineTypes.AntiAlias);
showMat(colorSourceImage, "warp > colorSourceImage", true);
foreach (var a in approx)
{
approx2.Add(new Point2f(a.X, a.Y));
}
foreach (var a in paperContour)
{
paperContour2.Add(new Point2f(a.X, a.Y));
}
Mat transmtx = Cv2.GetPerspectiveTransform(approx2, paperContour2);
Mat transformed = new Mat(sourceImage.Rows, sourceImage.Cols, MatType.CV_8UC3);
Cv2.WarpPerspective(sourceImage, transformed, transmtx, sourceImage.Size());
showMat(sourceImage, "warp > sourceImage", true);
}
private void showMat(Mat sourceImage, string title, bool isSave = false, bool isWaitable = false)
{
if (string.IsNullOrEmpty(title))
{
title = Guid.NewGuid().ToString();
}
// Cv2.ImShow(title, sourceImage);
if (isSave)
{
sourceImage.SaveImage($"{imagesResultPath}{MakeValidFileName(title)}.jpg");
}
if (isWaitable)
{
Cv2.WaitKey();
}
}
Output:
Source Image
Canny Image
Dilate Image
Erode Image
Drawed Image
Result