0

2 つの RGB 画像 (ppm 形式) があり、一番上の画像の純粋な黒ではないピクセルを一番下の画像にオーバーレイできるようにしたいと考えています。

画像の読み込み、画像の保存、画像のコピーは正常に実行できますが、上記の方法で 2 つの画像から画像を作成することはできません。

私が持っているすべてのコードを含めるつもりはありませんが、これを達成するための重要な部分は次のとおりです。

struct Pixel
{
    unsigned int r;
    unsigned int g;
    unsigned int b;
}

比較を容易にするために == 演算子をオーバーロードしました。

bool Pixel::operator==(const Pixel& other)
{
    if(r != other.r)
    {
        return true;
    }
    else if(g != other.g)
    {
        return true;
    }
    else if(b != other.b)
    {
        return true;
    }
    else
    {
        return false;
    }
}

私の Pic クラスには、次のメソッドがあります。

Pic Pic::overlay(const Pic& top, Pixel mask)
{    
    for(int h = 0; h < height; h++)
    {
        for(int w = 0; w < width; w++)
        {
            if(!(top.pixels[h][w] ==  mask))
            {
                pixels[h][w] = top.pixels[h][w];  // pixels[][] is a Pixel array
            }
        }
    }

    return *this;
}

私のメインファイルにはこれがあります:

Pic top;
Pic bot;
Pic overlay;

Pixel mask:
mask.r = 0;
mask.g = 0;
mask.b = 0;

top.loadimage("top.ppm");  //loadimage() loads the image in and all the data
bot.loadimage("bot.ppm");  //samme thing

overlay = bot.overlay(bot, mask);
overlay.saveimage("overlay.ppm");

= 演算子は、明らかに Pic クラスに対してオーバーロードされています。

私が抱えている問題の種類は次のとおりです。

オーバーレイ方式では、上記のif文をそのままにしておくと、保存したファイルにトップ画像が表示されます。!()の部分を無くすと下の画像が表示されます。

その if() ステートメントを完全に取り除き、単に個々のピクセルを変更しようとすると、次のようになります。

pixels[h][w].r = pixels[h][w].r - 50;

保存された画像は、明らかな理由で変更され、奇抜に見えます。

ただし... .b と .g は画像には影響しません。

アイデアがありません... 2日間これで遊んでいますが、何が問題なのかわかりません。このオーバーレイメソッドを除いて、すべてが私のプログラムで必要に応じて機能します。

編集:コードに問題の1つが見つかり、PPM P6形式で画像をロードする方法に戻りました。各ピクセルを 1 バイトとして個別にロードする代わりに、それらをすべて一緒にロードしようとしたため、圧縮からの構造とバイナリの読み取りで発生するクッションが作成されました...今、トップ画像のオーバーレイを上に置くことができます下の画像ですが、すべての色が表示されているわけではありません。それでも、前よりはまし。

これは、オーバーレイのネストされた for() ループを次のように変更したものです。

for(int h = 0; h < height; h++)
{
    for(int w = 0; w < width; w++)
    {
        if(top.pixels[h][w].r != mask.r &&
           top.pixels[h][w].g != mask.g &&
           top.pixels[h][w].b != mask.b   )
        {
            pixels[h][w].r = top.pixels[h][w].r;
            pixels[h][w].g = top.pixels[h][w].g;
            pixels[h][w].b = top.pixels[h][w].b;
        }

    }
}

明らかに、まだ作業が必要です。

4

1 に答える 1

1

この行は間違っているように見えます:

overlay = bot.overlay(bot, mask);

そうではありませんか:

overlay = bot.overlay(top, mask);

そして、平等テストをより短い方法で記述したい場合は、次のようにすることができます。

bool Pixel::operator==(const Pixel& other)
{
    return (r==other.r && g==other.g && b==other.b);
}

最後に、等値演算子を取得したので、追加と代入 ('=') を実行して、コーダーを可能な限りきれいに保ちます。

于 2013-05-22T09:55:55.473 に答える