3

我正在尝试检测此图像上的矩形:

在此处输入图像描述

使用此代码:

static void Main(string[] args)
{
    // Open your image
    string path = "test.png";
    Bitmap image = (Bitmap)Bitmap.FromFile(path);

    // locating objects
    BlobCounter blobCounter = new BlobCounter();

    blobCounter.FilterBlobs = true;
    blobCounter.MinHeight = 5;
    blobCounter.MinWidth = 5;

    blobCounter.ProcessImage(image);
    Blob[] blobs = blobCounter.GetObjectsInformation();

    // check for rectangles
    SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

    foreach (var blob in blobs)
    {
        List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob);
        List<IntPoint> cornerPoints;

        // use the shape checker to extract the corner points
        if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints))
        {
            // only do things if the corners form a rectangle
            if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle)
            {
                // here i use the graphics class to draw an overlay, but you
                // could also just use the cornerPoints list to calculate your
                // x, y, width, height values.
                List<Point> Points = new List<Point>();
                foreach (var point in cornerPoints)
                {
                    Points.Add(new Point(point.X, point.Y));
                }

                Graphics g = Graphics.FromImage(image);
                g.DrawPolygon(new Pen(Color.Red, 5.0f), Points.ToArray());

                image.Save("result.png");
            }
        }
    }
}

但它不识别矩形(墙)。它只识别大正方形,当我减小 minHeight 和 minWidth 时,它会识别字迹上的梯形..

4

4 回答 4

10

我提出了一种不同的算法方法,在使用图像处理算法将近一年之后,我可以说,要创建一个有效的算法,你必须像人类那样“反思”你是如何做到这一点的,这里是建议的方法:

  1. 我们并不真正关心纹理,我们关心边缘(矩形是边缘),因此我们将应用边缘检测>差异(http://www.aforgenet.com/framework/docs/html/d0eb5827- 33e6-c8bb-8a62-d6dd3634b0c9.htm),这给了我们:在此处输入图像描述

  2. 我们想夸大墙壁,作为人类,我们知道我们正在寻找墙壁,但计算机不知道这一点,因此,应用两轮 Morphology>Dilatation ( http://www.aforgenet.com/framework/docs /html/88f713d4-a469-30d2-dc57-5ceb33210723.htm),这给了我们:在此处输入图像描述

  3. 我们只关心什么是墙什么不是,应用二值化>阈值(http://www.aforgenet.com/framework/docs/html/503a43b9-d98b-a19f-b74e-44767916ad65.htm),我们得到: 在此处输入图像描述

  4. (可选)我们可以应用 blob 提取来擦除标签(“QUARTO、BANHEIRO”等)

  5. 我们应用颜色>反转,这只是因为下一步检测到白色而不是黑色。

  6. 应用 Blob>Processing>Connected Components Labeling ( http://www.aforgenet.com/framework/docs/html/240525ea-c114-8b0a-f294-508aae3e95eb.htm ),这将为我们提供所有矩形,如下所示:在此处输入图像描述

请注意,对于每个彩色框,您都有其坐标、中心、宽度和高度。因此,您可以使用该坐标从真实图像中提取片段。

PS:强烈建议使用 AForge Image Processing Lab 程序来测试您的算法。

于 2013-10-16T07:38:44.777 回答
0

如果您现在的问题是避免由于图像上的文字而产生噪音,请使用孔的宽度和高度小于最小矩形但大于任何文字的 FillHoles。

如果图像质量很好并且没有文字触及图像的边框,则反转图像和填充孔将删除大部分内容。

希望我正确理解了您的问题。

于 2014-09-18T06:30:43.960 回答
0

每次找到一个矩形时,都会在 Graphics 上绘制多边形,并且只为那个矩形保存文件。这意味着result.png一次只包含一个矩形。

尝试首先将所有矩形保存在 a 中List<List<Points>>,然后遍历它并将所有矩形添加到图像中。像这样的东西():

var image..
var rectangles..
var blobs..

foreach (blob in blobs)
{
    if (blob is rectangle)
    {
        rectangles.add(blob);
    }
}

foreach (r in rectangles)
{
   image.draw(r.points);
}

image.save("result.png");
于 2013-10-13T15:56:05.777 回答
0

我们正在尝试检测这么多矩形中的矩形(考虑网格的灰色矩形)。几乎所有的算法都会在这里混淆。您不会从输入图像中消除外部因素。为什么不用背景颜色替换网格线颜色或使用上面的阈值首先消除所有网格。

然后将所有像素增长为等于墙的宽度,然后使用数学查找所有水平和垂直线,使用检测到的线查找矩形。不受控制的填充将是有风险的,因为当边界未闭合时,填充会使两个房间成为一个矩形。

于 2017-02-24T08:14:19.823 回答