繁体   English   中英

如何检测图像中的彩色矩形?

[英]How to detect a colored rectangles in an image?

我正在尝试编写AI迷宫求解器程序。 为此,我将在GIMP中绘制2色迷宫,红色是墙壁,蓝色是背景或地板。 然后,我将从GIMP导出为png并使用ImageIO.read()获得迷宫的BufferedImage对象。 最后,我将Rectangle hitboxs分配给墙壁,并将它们存储在ArrayList以便可以使用.intersect()来检查精灵是否与墙壁接触。 我可以在这里使用它。

但是,我想对我的程序做一件事,我不知道该怎么做:将图像存储为BufferedImage ,如何检测红色部分(所有完全相同的RGB阴影)红色)并创建匹配的Rectangle s?

笔记:

  • 迷宫将始终具有固定大小(1000x1000像素)。
  • 每个迷宫都有一个固定的起点
  • 红色区域将始终形成直线矩形。 我创建的Rectangle对象仅用作hitbox,因此我可以使用.intersect() ,从不绘制或类似的东西。
  • 创建的Rectangle将存储在ArrayList

迷宫示例:(一个简单的例子 在此处输入图片说明

我想要做的是:(绿色区域是java.awt.Rectangles的创建位置,并存储在ArrayList

在此处输入图片说明

我将提供一种非常幼稚的方法来解决该问题(尚未完全实现,只是为了您能理解主意)。具有所有矩形的List<Rectangle> mazeRectangles 所有矩形都将存储在这里。当然,图像BufferedImage image; 现在,我们将遍历所有图片,直到找到一张具有正确颜色的图片。每次找到一个矩形时,我们将跳过所有x值以获取矩形的宽度。

//iterate over every pixel..
for (int y = 0; y < image.getHeight(); y++) {
    for (int x = 0; x < image.getWidth(); x++) {
        //check if current pixel has maze colour
        if(isMazeColour(image.getRGB(x, y))){
            Rectangle rect = findRectangle(x, y);
            x+=rect.width;
        }
    }
}

您检查颜色的方法:

public boolean isMazeColour(int colour){
    // here you should actually check for a range of colours, since you can
    // never expect to get a nicely encoded image..
    return colour == Color.RED.getRGB();
}

有趣的部分是findRectangle方法。.我们看是否已经存在一个包含我们坐标的Rectangle 如果是这样,则返回它,否则创建一个新的Rectangle ,将其添加到列表中并返回。 如果必须创建一个新的Rectangle ,我们将首先检查它的宽度。 烦人的部分是,您仍然必须检查矩形其余部分的每个像素,因为您可能具有如下配置:

+++++++
+++++++
###
###

其中#+是单独的框。 所以我们首先找到宽度:

public Rectangle findRectangle(int x, int y){
    // this could be optimized. You could keep a separate collection where
    // you remove rectangles from, once your cursor is below that rectangle
    for(Rectangle rectangle : mazeRectangles){ 
        if(!rectangle.contains(x, y)){
            return rectangle;
        }
    }
    //find the width of the `Rectangle`
    int xD = 0;
    while(x+xD < width && isMazeColour(image.getRGB(x+xD+1, y))){
        xD++;
    }

    int yD = 0; //todo: find height of rect..

    Rectangle toReturn = new Rectangle(x, y, xD, yD);
    mazeRectangles.add(toReturn);
    return toReturn;
}

我没有实现yD部分,因为它有点混乱并且有点懒,但是您需要遍历y并检查每一行(因此有两个嵌套循环)

请注意,此算法可能会导致Rectangle重叠。 如果您不希望这样做,请在查找xD检查每个像素是否已包含在Rectangle 只要您不在另一个Rectangle ,请仅扩展xD

另一件事:由于红色和蓝色之间的颜色插值,您最终可能会在矩形的边界处留下奇怪的伪像。 也许您想检查矩形是否变小(例如只有1像素宽),并摆脱它们。

去年,有人问到解决迷宫的更一般的情况。 它们还有一个额外的复杂性,那就是有多条路径,但是通过交叉点的“正确”路径是笔直的。

Python:解决“ N对N”迷宫

提供的解决方案通过射线投射解决了迷宫问题。 从路径的起点开始,它将沿所有方向沿路径向下投射线条。 然后,它对列表进行排序并选择最长的线,然后使用该线来计算下一个起点。 现在,它会在所有方向上重复投影线, 除了其到达的方向 -回溯可能会比前进进度更长。 那只会在迷宫中最长的腿周围反弹解决方案。

如果确定角度始终为90度,则可以相应地修改代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM