0

对于这个问题:是否有合适的算法来检测图形的背景颜色?,我将需要创建一个填充算法,以便能够将我的所有像素分成相同颜色的组。

我递归地这样做了,但它给了我一个堆栈溢出错误。所以我不得不选择在这里找到的基于队列的迭代算法:http ://en.wikipedia.org/wiki/Flood_fill#Alternative_implementations

首先,我开始搜索所有矩阵元素(元素是Pixel类的实例)。

private PixelGroup[] generatePixelGroupsFromMatrix(Pixel[][] matrix) {
    PixelGroup[] tempGroups = new PixelGroups[9999999]; // Nevermind the 9999999....
    int groupsFound = 0;
    Pixel pixel;

    for (int y = 0; y < matrix.length; ++y) {
        for (int x = 0; x < matrix[0].length; ++x) {
            pixel = matrix[y][x];
            if (!pixel.evaluated) {
                // This pixel has never been evaluated
                // Therefore, it belongs to a new group
                // First, we make a new group
                PixelGroup newGroup = new PixelGroup();
                // Begin search for connected pixels with the same color. All pixels found will belong to this new group.
                findPixelsConnectedWith(pixel,newGroup);
                tempGroups[groupsFound] = newGroup;
                ++groupsFound;
            }
        }
    }

    PixelGroup[] result = new PixelGroup[groupsFound];
    for (int i = 0; i < groupsFound; ++i) {
        result[i] = tempGroups[i];
    }

    return result;
}

因此,Pixel具有以下值:x、y、评估(布尔)和颜色(整数)。然后,PixelGroup只是一个能够保存像素的类(它有效)。

这是给我带来麻烦的方法:

private void findPixelsConnectedWith(Pixel pixel, GroupOfPixels group) {
    QueueOfPixels queue = new QueueOfPixels();
    queue.add(pixel);

    Pixel currentPixel;
    int x,y;
    Pixel neighbor;
    while((currentPixel = queue.nextPixel()) != null) {
        if (currentPixel.color == pixel.color && !currentPixel.evaluated) {
            // This pixel has the required color, and has not been evaluated. It meets our needs.
            // Add to group.
            group.addPixel(currentPixel);
            // Flag it as evaluated. So in the future, it will be ignored.
            currentPixel.evaluated = true;
            // Evaluate all 8 possible directions to find neighbor pixels
            int[] xDirections = {0,1,1,1,0,-1,-1,-1};
            int[] yDirections = {-1,-1,0,1,1,1,0,-1};
            for (int i = 0; i < 8; ++i) {
                x = xDirections[i];
                y = yDirections[i];
                if (pixelExists(currentPixel.y + y,currentPixel.x + x)) {
                    // There exists a pixel in this direction!
                    neighbor = getPixel(currentPixel.y + y,currentPixel.x + x);
                    queue.add(neighbor);
                }
            }
        }
    }

}

如果你好奇,这是我的QueueOfPixels课。我必须只用向量(学校作业要求)自己制作:https ://codereview.stackexchange.com/questions/17823/vector-based-flood-fill-algorithm-queue-class (据我所知,它很简单)。

问题是什么?

好吧,我已经用这张 5x2 像素的图像进行了测试(你需要放大很多才能看到它):http: //i.stack.imgur.com/xV0Lf.gif - 第一行只有黑色像素,第二个它们是白色的。程序告诉我它找到了6 个像素组(本来应该只有 2 个!)

我尝试过什么来调试问题?

好吧,首先,在调用 findPixelsConnectedWith 之前,我放置了这一行:

System.out.println("The pixel (" + x + "," + y + ") has not been evaluated. Evaluating now.");

结果是这样的:

The pixel (0,0) has not been evaluated. Evaluating now.
The pixel (1,0) has not been evaluated. Evaluating now.
The pixel (2,0) has not been evaluated. Evaluating now.
The pixel (3,0) has not been evaluated. Evaluating now.
The pixel (4,0) has not been evaluated. Evaluating now.
The pixel (0,1) has not been evaluated. Evaluating now.

因此,如您所见,代码似乎无法处理第一行(黑色像素),因为它认为该行中的每个像素都没有被评估(我希望它会说 (0,0) 是未评估和完成)。但是当它开始使用第二行时,它似乎确实按预期工作(找到(0,1)然后结束)。

但我仍然无法找出发生了什么。有任何想法吗?

编辑: 我的getPixelpixelExists功能:

private boolean pixelExists(int y, int x) {
    return (y > 0 && y < pixelMatrix.length) && (x > 0 && x < pixelMatrix[0].length);
}

private Pixel getPixel(int y, int x) {
    return pixelMatrix[y][x];
}
4

2 回答 2

1

您的 pixelExists 方法应使用 y >= 0 和 x >= 0 而不是 y > 0 和 x > 0。

private boolean pixelExists(int y, int x) {
    return (y >= 0 && y < pixelMatrix.length) && (x >= 0 && x < pixelMatrix[0].length);
}

这可能不是唯一的问题,但它肯定会阻止你得到正确的答案。

于 2012-10-23T01:31:13.350 回答
0

Maybe pixelExists method has "y > 0" part while it should has "y>=0"?

于 2012-10-23T00:46:41.740 回答