3

ぼかそうとしている画像がありますが、実際には非常に奇妙に見えます。

ここに画像の説明を入力してください

私がしていることはこれです:私は各ピクセルを取り、その値を色ごとに隣接するすべてのピクセルの値と平均します。

またはそう思います。しかし、そこには明らかにエラーがあり、forループに問題があるのではないかと思いますが、私の人生では、実際に何が問題になっているのかを知ることができません。

特に、ステップ5(出力ステップ)は、画像がまだ順序付けられていることを示しています。ブラーマスクされた画像ではなく、左側の画像を右側に出力した場合、ピクセルは正しい順序のままです。

    try
{
    // STEP ONE: MAKE MEMORY AVAILABLE FOR IMAGE
    int ***image;
    image = new int**[m_nSizeX];
    for(int i = 0; i < m_nSizeX; ++i)
    {
        image[i] = new int*[m_nSizeY];
        for(int j = 0; j < m_nSizeY; ++j)
        {
            image[i][j] = new int[nrPixels];// image[x][y][z] is now a pointer to an int

        }
    }

    // STEP TWO: MAKE MEMORY AVAILABLE FOR IMAGE MASK
    int ***mask;
    mask = new int**[m_nSizeX];
    for(int i = 0; i < m_nSizeX; ++i)
    {
        mask[i] = new int*[m_nSizeY];
        for(int j = 0; j < m_nSizeY; ++j)
        {
            mask[i][j] = new int[nrPixels];// mask[x][y][z] is now a pointer to an int

        }
    }

    //STEP THREE: COPY IMAGE INTO MEMORY

    unsigned long lOffset = 0;
    for(long i=0; i<m_nSizeX ; i++)
    {
        for(long j=0; j<m_nSizeY ; j++)
        {
            for(int k=0; k<(nrPixels) ; k++)
            {
                image[i][j][k] = *(reinterpret_cast<unsigned char*>(m_pcMemOrg + lOffset) );
                lOffset++;
            }
        }
    }

    // STEP FOUR: BLUR IMAGE

    for(long i=0; i<m_nSizeX ; i++)
    {
        for(long j=0; j<m_nSizeY ; j++)
        {
            for(int k=0; k<(nrPixels) ; k++)
            {
                // INSERT BLURRING FUNCTION HERE (New value = Old value averaged with adjacent pixels)

                if(k != 2) // 0 = blue, 1 = green, 2 = red;
                {
                    mask[i][j][k] = 0;
                }
                else


                if(i==0 && j==0)// (0,0) Corner Pixel
                {
                    mask[i][j][k] = (image[i][j][k]+image[i+1][j][k]+image[i][j+1][k]+image[i+1][j+1][k])/4;
                }
                else if(i==0 && j==(m_nSizeY-1))// (0,yMax) Corner Pixel
                {
                    mask[i][j][k] = (image[i][j][k]+image[i+1][j][k]+image[i][j-1][k]+image[i+1][j-1][k])/4;
                }
                else if(i==(m_nSizeX-1) && j==0)// (xMax,0) Corner Pixel
                {
                    mask[i][j][k] = (image[i][j][k]+image[i-1][j][k]+image[i][j+1][k]+image[i-1][j+1][k])/4;
                }
                else if(i==(m_nSizeX-1) && j==(m_nSizeY-1))// (xMax,yMax) Corner Pixel
                {
                    mask[i][j][k] = (image[i][j][k]+image[i-1][j][k]+image[i][j-1][k]+image[i-1][j-1][k])/4;
                }
                else if(i==0)// (0,---) Edge Pixels
                {
                    mask[i][j][k] = (image[i][j][k]+image[i][j+1][k]+image[i+1][j+1][k]+image[i+1][j][k]+image[i+1][j-1][k]+image[i][j-1][k])/6;
                }
                else if(j==0)// (---,0) Edge Pixels
                {
                    mask[i][j][k] = (image[i][j][k]+image[i-1][j][k]+image[i-1][j+1][k]+image[i][j+1][k]+image[i+1][j+1][k]+image[i+1][j][k])/6;                    
                }
                else if(i==(m_nSizeX-1))// (xMax,---) Edge Pixels
                {
                    mask[i][j][k] = (image[i][j][k]+image[i][j-1][k]+image[i-1][j-1][k]+image[i-1][j][k]+image[i-1][j+1][k]+image[i][j+1][k])/6;
                }
                else if(j==(m_nSizeY-1))// (---,yMax) Edge Pixels
                {
                    mask[i][j][k] = (image[i][j][k]+image[i+1][j][k]+image[i+1][j-1][k]+image[i][j-1][k]+image[i-1][j-1][k]+image[i-1][j][k])/6;
                }
                else // Mid-Image Pixels
                {
                    mask[i][j][k] = (image[i][j][k]+image[i][j+1][k]+image[i+1][j+1][k]+image[i+1][j][k]+image[i+1][j-1][k]+image[i][j-1][k]+image[i-1][j-1][k]+image[i-1][j][k]+image[i-1][j+1][k])/9;
                }
            }
        }
    }

    //STEP FIVE: OUTPUT BLURRED IMAGE
    lOffset = 0;

    for(long i=0; i<m_nSizeX ; i++)
    {
        for(long j=0; j<m_nSizeY ; j++)
        {
            for(int k=0; k<(nrPixels) ; k++)
            {
                *(reinterpret_cast<unsigned char*>(m_pcMemInv + lOffset) ) = mask[i][j][k];
                //*(reinterpret_cast<unsigned char*>(m_pcMemInv + lOffset) ) = image[i][j][k];
                lOffset++;
            }
        }
    }


    // STOP USING IMAGE MEMORY NOW

    for (int i = 0; i < m_nSizeX; ++i) {
        for (int j = 0; j < m_nSizeY; ++j)
            delete [] image[i][j];

        delete [] image[i];
    }
    delete [] image;

    // STOP USING MASK MEMORY NOW
    for (int i = 0; i < m_nSizeX; ++i) {
        for (int j = 0; j < m_nSizeY; ++j)
            delete [] mask[i][j];

        delete [] mask[i];
    }
    delete [] mask;
}
catch( ... )
{

}
4

2 に答える 2

2

多次元インデックスを使用する場合、通常、最初のインデックスはy、2番目xと3番目red/green/blueです-、、を使用した非標準の転置レイアウトを使用します。ここで、i水平インデックスを意味するようです(と比較すると)。jkim_nSizeX

あなたの画像は、最初にコピーしたときに転置され、不思議な方法で変換され、2回目にコピーしたときに元に戻されていると思います。詳細を推測することはできませんが、寸法を正しくするようにアドバイスするだけで十分です(スワップij)。

ちなみに、呼び出しは通常の名前を調整し、x(とyの代わりにijまたは多分ji?)が役立ちます。

于 2012-07-18T18:17:46.250 に答える
0

の種類は表示されませんがm_pcMemOrg、必要なという事実に基づいて、そうではreinterpret_castないと思いますunsigned char。さらに重要なことに、私はそれが1つではないと思いますsizeof(*m_pcMemOrg)。したがって、オフセットを追加すると、オフセットにタイプのサイズが乗算されます。

交換:

image[i][j][k] = *(reinterpret_cast<unsigned char*>(m_pcMemOrg + lOffset) );

と:

image[i][j][k] = *(reinterpret_cast<unsigned char*>(m_pcMemOrg) + lOffset );

同様に、出力コードも使用します。

余談ですが、他の人は、これが画像を保存してトラバースするためのひどく非効率的な方法であると指摘するのは正しいです。1次元配列が最適であり、次の式を使用してインデックスが付け[j*stride + i*nrPixels + k]られますstride = m_nSizeX*nrPixelsiまた、ループとループを交換し、代わりに名前としてjとを使用xします。y

于 2012-07-18T18:47:00.347 に答える