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-最初の行には黒のピクセル、そして2番目は白です。プログラムは、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)は評価されたと予想していました)評価および実行されていません)。しかし、2行目で動作を開始すると、期待どおりに動作しているように見えます((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

たぶん、pixelExistsメソッドには「y> = 0」の部分がありますが、「y> = 0」である必要がありますか?

于 2012-10-23T00:46:41.740 に答える