Beispiel #1
0
        // Apply a Gaussian filter of size filtersz - separable implementation
        private MultiDimFloatTexture applyGaussianFilter_Separable(int filtersz)
        {
            // . compute Gauss kernel
            MultiDimFloatTexture kernel = new MultiDimFloatTexture(filtersz, 1, 1);
            float sum = 0;

            for (int i = 0; i < filtersz; i++)
            {
                float di    = (float)(i - filtersz / 2);
                float u2    = (di * di) / ((float)filtersz * filtersz);
                float sigma = 1.0f / 3.0f; // > 3 std dev => assume 0
                kernel.set((float)Math.Exp(-u2 / (2.0f * sigma * sigma)), i, 0, 0);
                sum += kernel.get(i, 0, 0);
            }

            // . normalize
            for (int i = 0; i < filtersz; i++)
            {
                kernel.set(kernel.get(i, 0, 0) / sum, i, 0, 0);
            }

            // . alloc result and tmp buffer (initialized to 0)
            MultiDimFloatTexture tmp = new MultiDimFloatTexture(m_iW, m_iH, m_iNumComp);
            MultiDimFloatTexture res = new MultiDimFloatTexture(m_iW, m_iH, m_iNumComp);

            // . convolve - pass 1  (treat texture as toroidal)
            for (int v = 0; v < m_iH; v++)
            {
                for (int u = 0; u < m_iW; u++)
                {
                    for (int i = 0; i < filtersz; i++)
                    {
                        int x = u + i - filtersz / 2;
                        int y = v;

                        for (int c = 0; c < numComp(); c++)
                        {
                            float val = tmp.get(u, v, c);
                            tmp.set(val + ((float)getmod(x, y, c)) * kernel.get(i, 0, 0), u, v, c);
                        }
                    }
                }
            }
            // . convolve - pass 2  (treat texture as toroidal)
            for (int v = 0; v < m_iH; v++)
            {
                for (int u = 0; u < m_iW; u++)
                {
                    for (int j = 0; j < filtersz; j++)
                    {
                        int x = u;
                        int y = v + j - filtersz / 2;
                        for (int c = 0; c < m_iNumComp; c++)
                        {
                            float val = res.get(u, v, c);
                            res.set(val + ((float)tmp.getmod(x, y, c)) * kernel.get(j, 0, 0), u, v, c);
                        }
                    }
                }
            }

            kernel = null;
            tmp    = null;
            return(res);
        }