检测图像AForge中的小矩形

时间:2013-09-18 12:34:54

标签: c# aforge

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

enter image description here

使用此代码:

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时,它识别出写作上的梯形..

3 个答案:

答案 0 :(得分:10)

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

  1. 我们并不关心纹理,我们关心边缘(矩形是边缘),因此我们将应用边缘检测&gt;差异(http://www.aforgenet.com/framework/docs/html/d0eb5827-33e6-c8bb-8a62-d6dd3634b0c9.htm),这给了我们:{ {0}}

  2. 我们想要夸大墙壁,因为人类我们知道我们正在寻找墙壁,但计算机并不知道这一点,因此,应用两轮形态学&gt; Dilatation(http://www.aforgenet.com/framework/docs/html/88f713d4-a469-30d2-dc57-5ceb33210723.htm),这给了我们:enter image description here

  3. 我们只关心什么是墙和什么不是,应用二值化&gt;阈值(http://www.aforgenet.com/framework/docs/html/503a43b9-d98b-a19f-b74e-44767916ad65.htm),我们得到: enter image description here

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

  5. 我们应用了一个Color&gt; Invert,这只是因为下一步检测到白色而不是黑色。

  6. 应用Blob&gt;处理&gt;连接组件标签(http://www.aforgenet.com/framework/docs/html/240525ea-c114-8b0a-f294-508aae3e95eb.htm),这将为我们提供所有矩形,如下所示:enter image description here

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

    PS:强烈建议使用AForge图像处理实验室来测试你的算法。

答案 1 :(得分:0)

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

首先尝试保存List<List<Points>>中的所有矩形,然后检查它并将所有矩形添加到图像中。这样的事情( Pseudo ):

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");

答案 2 :(得分:0)

如果你现在的问题是为了避免因图像上的文字引起的噪音,请使用FillHoles,其中孔的宽度小于最小的矩形,但大于任何一个文字。

如果图像质量良好且没有文字触及图像的边框,则反转图像,FillHoles将删除大部分内容。

希望我能正确理解你的问题。