Exemplo n.º 1
0
        public Quantizer(MultiDimFloatTexture tex, int qbits, float percent)
        {
            Globals.Assert(percent > 0.0f && percent <= 100.0f);
            ScopeTimer tm = new ScopeTimer("[Quantizer]");

            m_Texture   = tex;
            m_Quantized = new MultiDimIntTexture(tex.width(), tex.height(), tex.numComp());

            m_iQBits = qbits;

            m_Mean   = new float[tex.numComp()];
            m_StdDev = new float[tex.numComp()];
            m_Center = new float[tex.numComp()];
            m_Radius = new float[tex.numComp()];

            // . compute std dev and mean of every components

            float [] sum   = new float[tex.numComp()];
            float [] sumsq = new float[tex.numComp()];

            for (int j = 0; j < tex.height(); j++)
            {
                for (int i = 0; i < tex.width(); i++)
                {
                    for (int c = 0; c < tex.numComp(); c++)
                    {
                        float f = tex.get(i, j, c);
                        sum[c]   += f;
                        sumsq[c] += f * f;
                    }
                }
            }

            float num = (float)(tex.width() * tex.height());

            for (int c = 0; c < tex.numComp(); c++)
            {
                m_Mean[c] = sum[c] / num;
                float sqstddev = (sumsq[c] - sum[c] * sum[c] / num) / (num - 1.0f);
                if (sqstddev > BMathLib.cFloatCompareEpsilon)
                {
                    m_StdDev[c] = (float)Math.Sqrt(sqstddev);
                }
                else
                {
                    m_StdDev[c] = 0.0f;
                }
            }

            // . for every component
            //      compute center and radius so that 'percent' samples are within quantization space
            for (int c = 0; c < tex.numComp(); c++)
            {
                float [] samples = new float[tex.width() * tex.height()];
                // add samples to array
                for (int j = 0; j < tex.height(); j++)
                {
                    for (int i = 0; i < tex.width(); i++)
                    {
                        samples[i + j * tex.width()] = tex.get(i, j, c);
                    }
                }

                // sort array
                Sort.RadixSort rs = new Sort.RadixSort();
                rs.Sort(samples);//sort(samples.begin(),samples.end());

                // find left and right elements so that 'percent' elements are inside
                float pout  = ((100.0f - percent) / 2) / 100.0f;
                int   left  = (int)((samples.Length - 1) * pout);
                int   right = (int)((samples.Length - 1) * (1.0f - pout));
                m_Center[c] = (samples[right] + samples[left]) / 2.0f;
                m_Radius[c] = samples[right] - samples[left];
            }

            // . quantize
            int num_outside = 0;

            for (int j = 0; j < tex.height(); j++)
            {
                for (int i = 0; i < tex.width(); i++)
                {
                    if (!quantizePixel(tex.numComp(), tex, tex.getpixIndex(i, j), m_Quantized.getpixIndex(i, j)))
                    {
                        num_outside++;
                    }
                }
            }

            float percent_out = num_outside * 100.0f / (tex.width() * tex.height());


            if (Globals.PRINT_DEBUG_MSG)
            {
                Debug.Print("-----------.>> Quantizer: num outside = " + percent_out + "%");
            }
            tm.destroy();
            tm = null;
        }
Exemplo n.º 2
0
        int computeStackLevels_Box(MultiDimFloatTexture tex, ref MultiDimFloatTexture[] _lvls)
        {
            List <MultiDimFloatTexture> tmplvls = new List <MultiDimFloatTexture>();

            // compute stack of averages on large texture
            // . add unmodifed finest level
            tmplvls.Clear();
            tmplvls.Add(tex);
            int l = 0;

            MultiDimFloatTexture lvl = tex;

            float [] lvlDat = lvl.getData();
            int      num    = (int)(0.01 + BMathLib.log2((float)lvl.getWidth()));

            do                                                       // TODO: speed this up - extremely unefficient !!! (not critical though)
            {
                stack_accessor_v2 access = new stack_accessor_v2(l); // l is destination level for children
                                                                     // (children *are* at level l)

                MultiDimFloatTexture stackl = new MultiDimFloatTexture(lvl.getWidth(), lvl.getHeight(), lvl.numComp());

                List <float> avg = new List <float>();
                for (int q = 0; q < lvl.numComp(); q++)
                {
                    avg.Add(0);
                }

                for (int i = 0; i < stackl.getWidth(); i++)
                {
                    for (int j = 0; j < stackl.getHeight(); j++)
                    {
                        for (int q = 0; q < avg.Count; q++)
                        {
                            avg[q] = 0;
                        }

                        for (int li = 0; li < 2; li++)
                        {
                            for (int lj = 0; lj < 2; lj++)
                            {
                                int ci = 0, cj = 0;
                                access.child_ij(i, j, li, lj, ref ci, ref cj);
                                //CLM large amount of modification here.. check back w/ origional if problems occur
                                if (ci < 0 || ci >= lvl.getWidth() ||
                                    cj < 0 || cj >= lvl.getHeight())
                                {
                                    continue;
                                }

                                int idx = lvl.getpixmodIndex(ci, cj);
                                for (int c = 0; c < stackl.numComp(); c++)
                                {
                                    avg[c] += lvlDat[idx + c];
                                }
                            }
                        }


                        int opix = stackl.getpixIndex(i, j);
                        for (int c = 0; c < stackl.numComp(); c++)
                        {
                            stackl.getData()[opix + c] = avg[c] / 4.0f;
                        }
                    }
                }

                lvl = stackl;
                tmplvls.Add(lvl);
                l++;
            }  while ((1 << l) <= lvl.getWidth());

            // clamp stack
            int w = tex.getWidth() / 2;
            int h = tex.getHeight() / 2;

            _lvls = new MultiDimFloatTexture[m_iNbLevels];

            l = 0;
            int sz = w;

            for (int i = 0; i < tmplvls.Count; i++)
            {
                MultiDimFloatTexture ktex    = tmplvls[i];
                MultiDimFloatTexture clamped = ktex.extract(w / 2, h / 2, w, h);
                _lvls[i] = clamped;

                l++;
                sz >>= 1;
                if (sz < 1)
                {
                    break;
                }
            }

            for (int i = 0; i < tmplvls.Count; i++)
            {
                tmplvls[i] = null;
            }

            tmplvls.Clear();

            return((int)_lvls.Length);
        }