You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCvSharp的图像纠偏与透视变换问题求助

OpenCvSharp图像纠偏与透视变换问题求助

我需要在使用Tesseract扫描文本前,通过OpenCvSharp完成图像的纠偏与透视变换处理,但目前的代码运行后未能得到正确的纠偏和变换效果,以下是我的代码片段及各步骤的图像结果,恳请各位提供技术帮助。

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

各步骤图像

  • 原始图像
    原始图像
  • 源图像
    源图像
  • Canny图像
    Canny图像
  • 膨胀图像
    膨胀图像
  • 腐蚀图像
    腐蚀图像
  • 轮廓绘制图像
    轮廓绘制图像
  • 结果图像
    结果图像

内容的提问来源于stack exchange,提问作者Kerberos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:53:15