如何避免MinAreaRect检测到的直肠旋转? [英] How to avoid rotation of rects, detected by MinAreaRect?

查看:78
本文介绍了如何避免MinAreaRect检测到的直肠旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图检测Windows窗体上的文本字段,但CvInvoke.MinAreaRect(contour)返回以-7.29419661角度旋转的矩形.

I am trying to detect text fields on Windows Form but CvInvoke.MinAreaRect(contour) returns rectangle, rotated by -7.29419661 Angle.

我的代码是

        Image<Bgr, Byte> a =
          new Image<Bgr, byte>(@"d:/Art/documents/Projects/InputFieldsDetector/Images/Form345_1.PNG");

        imageBox1.Image = a;

        UMat grayed = new UMat();
        CvInvoke.CvtColor(a, grayed, ColorConversion.Bgr2Gray);
        imageBox2.Image = grayed;

        UMat canny = new UMat();
        CvInvoke.Canny(grayed, canny, 50, 200, 3);
        imageBox3.Image = canny;

        VectorOfVectorOfPoint cnts = new VectorOfVectorOfPoint();

        UMat hierarchy = new UMat();
        CvInvoke.FindContours(canny, cnts, null, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);

        Image<Bgr, Byte> justCountor = a.Clone();

        List<string> sizes = new List<string>();

        int count = cnts.Size;
        for (int i = 0; i < count; i++)
        {
            VectorOfPoint contour = cnts[i];
            var area = CvInvoke.ContourArea(contour);
            //if (area > 10000 && area < 15000)
            if (area > 200 && area < 300)
            {
                sizes.Add(area.ToString());

                Point[] pts = contour.ToArray();
                var forDraw = CvInvoke.MinAreaRect(contour);
                // forDraw.Angle = 0;
                //forDraw.Center.Y += 10;

                justCountor.Draw(forDraw, new Bgr(Color.DarkOrange), 2);
            }
        }
        imageBox4.Image = justCountor;

        List<double> result = sizes.Select(x => double.Parse(x)).ToList();

        result.Sort();
        sizes = result.Select(x => x.ToString()).ToList();

        File.WriteAllLines("c:/temp/qqq.txt", sizes);

原始图片是:

如果我取消评论

            forDraw.Angle = 0;
            forDraw.Center.Y += 10;

检测到的矩形的大小类似于字段的大小...

sizes of detected rects are similar to sizes of fields...

请告诉我,为什么退回的矩形旋转,如何解决?

Tell me, please, why returned rects are rotated and how to fix that?

推荐答案

您可以在Canny输出中看到,该算法将阴影解释为边界.最简单的修复方法是使用接近框背景白色的阈值对图像进行预过滤.

You can see in the Canny output that the algorithm is interpreting the shadows as borders. The easiest way to fix that is prefilter the image with a threshold with a high value near to the white of the box background.

Image<Bgr, Byte> a =
              new Image<Bgr, byte>(@"d:/Art/documents/Projects/InputFieldsDetector/Images/Form345_1.PNG");

imageBox1.Image = a;

UMat grayed = new UMat();
CvInvoke.CvtColor(a, grayed, ColorConversion.Bgr2Gray);
imageBox2.Image = grayed;

UMat thresholded = new UMat();
CvInvoke.Threshold(grayed, thresholded, 128, 255, ThresholdType.Binary);
imageBox5.Image = thresholded;

UMat canny = new UMat();
CvInvoke.Canny(thresholded, canny, 50, 200, 3);
imageBox3.Image = canny;

VectorOfVectorOfPoint cnts = new VectorOfVectorOfPoint();

UMat hierarchy = new UMat();
CvInvoke.FindContours(canny, cnts, null, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);

Image<Bgr, Byte> justCountor = a.Clone(); 
List<string> sizes = new List<string>(); 
int count = cnts.Size;
for (int i = 0; i < count; i++)
{
    VectorOfPoint contour = cnts[i];
    var area = CvInvoke.ContourArea(contour);
    if (area > 200 && area < 300)
    {
        sizes.Add(area.ToString());
        Point[] pts = contour.ToArray();
        var forDraw = CvInvoke.MinAreaRect(contour);

        // forDraw.Angle = 0;
        //forDraw.Center.Y += 10;

        if (forDraw.Angle==0)
            justCountor.Draw(forDraw, new Bgr(Color.DarkOrange), 2);
    }
}
imageBox4.Image = justCountor;

List<double> result = sizes.Select(x => double.Parse(x)).ToList();
result.Sort();
sizes = result.Select(x => x.ToString()).ToList();
File.WriteAllLines("c:/temp/qqq.txt", sizes);

这篇关于如何避免MinAreaRect检测到的直肠旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆