3

我有一张我试图模糊的图像,但它最终看起来确实很奇怪:

在此处输入图像描述

我所做的是:我获取每个像素,并在逐个颜色的基础上将其值与所有相邻像素的值进行平均。

或者我认为。但是那里显然有一个错误,我怀疑我的 for 循环有问题,但对于我的生活,我无法找出实际出了什么问题。

特别是,第五步(输出步骤)显示图像仍然是有序的——如果我在右侧输出左侧图像,而不是模糊蒙版的图像,像素仍然是正确的顺序。

    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,第二个x和第三个red/green/blue- 您使用非标准转置布局ijk,其中i似乎意味着水平索引(看到您将其与 进行比较m_nSizeX)。

我猜你的图像在第一次复制时被转置,以一种神秘的方式转换,并在第二次复制时转回;我无法猜测细节,但建议您将尺寸正确(交换ij)就足够了。

顺便说一句,调用协调正常名称xand y(而不是iand j,或者也许jand i?)会有所帮助。

于 2012-07-18T18:17:46.250 回答
0

您没有显示 的​​类型m_pcMemOrg,但基于您需要 a 的事实,reinterpret_cast我猜它不是unsigned char。更重要的是我认为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 );

输出代码也是如此。

顺便说一句,其他人指出这是一种非常低效的存储和遍历图像的方式是正确的。一维数组是最好的,使用公式[j*stride + i*nrPixels + k]where 进行索引stride = m_nSizeX*nrPixels。我也会交换iandj循环,并使用xandy作为名称。

于 2012-07-18T18:47:00.347 回答