对于这个问题:Is there a proper algorithm for detecting the background color of a figure?,我需要创建一个flood-fill algorithm,以便能够将相同颜色的组中的所有像素分开。
我递归地做了这个,但它给了我一个堆栈溢出错误。所以我必须选择这里找到的迭代,基于队列的算法: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,evaluate(布尔值)和颜色(整数)。
然后,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)然后它结束了。)
但我仍然无法知道发生了什么。有什么想法吗?
修改
我的getPixel
和pixelExists
功能:
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];
}
答案 0 :(得分:1)
您的pixelExists方法应使用y&gt; = 0和x&gt; = 0而不是y&gt; 0和x> 0
private boolean pixelExists(int y, int x) {
return (y >= 0 && y < pixelMatrix.length) && (x >= 0 && x < pixelMatrix[0].length);
}
这可能不是唯一的问题,但肯定会阻止您获得正确答案。
答案 1 :(得分:0)
也许pixelExists方法有&#34; y&gt; 0&#34;它应该有&#34; y&gt; = 0&#34;?