void computeProjectedSynthNeighborhoods(List <PCA /*_Synth*/> pcaSynth) { bool clean_neigh = false; // if synth neighborhoods not available, compute them if (m_SynthNeighborhoods == null) { computeSynthNeighborhoods(); clean_neigh = true; } { ScopeTimer tm = new ScopeTimer("[computeProjectedSynthNeighborhoods]"); m_ProjectedSynthNeighborhoods = new NeighborhoodSynth[mNumLevels][]; // foreach level for (int l = 0; l < mNumLevels; l++) { m_ProjectedSynthNeighborhoods[l] = new NeighborhoodSynth[mOwner.recoloredStack(l).getWidth() * mOwner.recoloredStack(l).getHeight()]; for (int j = 0; j < mOwner.recoloredStack(l).getHeight(); j++) { for (int i = 0; i < mOwner.recoloredStack(l).getWidth(); i++) { m_ProjectedSynthNeighborhoods[l][i + j * mOwner.recoloredStack(l).getWidth()] = new NeighborhoodSynth(); NeighborhoodSynth neigh = m_SynthNeighborhoods[l][i + j * mOwner.recoloredStack(l).getWidth()]; NeighborhoodSynth proj = m_ProjectedSynthNeighborhoods[l][i + j * mOwner.recoloredStack(l).getWidth()]; pcaSynth[l].project(neigh, Globals.NUM_RUNTIME_PCA_COMPONENTS, ref proj); proj.setIJ(i, j); } } } tm.destroy(); tm = null; } // clean RT neighborhoods if (clean_neigh) { m_SynthNeighborhoods = null; } }
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; }
// ----------------------------------------------------- MultiDimFloatTexture enlargeTexture(MultiDimFloatTexture ex, int type) { ScopeTimer tm = new ScopeTimer("[Exemplar::enlargeTexture]"); int w = ex.getWidth(); int h = ex.getHeight(); MultiDimFloatTexture large = new MultiDimFloatTexture(w * 2, h * 2, ex.numComp()); for (int j = 0; j < h * 2; j++) { for (int i = 0; i < w * 2; i++) { int ri, rj; // where to read ? if (type == 0) { // Toroidal // ri if (i < w / 2) { ri = (i + w / 2) % w; } else if (i < w + w / 2) { ri = i - w / 2; } else { ri = ((i - w / 2) % w); } // rj if (j < h / 2) { rj = (j + h / 2) % h; } else if (j < h + h / 2) { rj = j - h / 2; } else { rj = ((j - h / 2) % h); } } else { // Mirror // ri if (i < w / 2) { ri = (w / 2 - i); } else if (i < w + w / 2) { ri = i - w / 2; } else { ri = (w - 1 - (i - (w / 2 + w))); } // rj if (j < h / 2) { rj = (h / 2 - j); } else if (j < h + h / 2) { rj = j - h / 2; } else { rj = (h - 1 - (j - (h / 2 + h))); } } for (int c = 0; c < ex.numComp(); c++) { large.set(ex.get(ri, rj, c), i, j, c); } } } tm.destroy(); tm = null; return(large); }
void computeSynthNeighborhoods() { ScopeTimer tm = new ScopeTimer("[computeSynthNeighborhoods]"); m_SynthNeighborhoods = new NeighborhoodSynth[mNumLevels][]; // foreach level for (int level = 0; level < mNumLevels; level++) { MultiDimFloatTexture recolored_level = null; if (Globals.isDefined("4D")) { // . keep only 4 dimension from recolored exemplar MultiDimFloatTexture level_4D = new MultiDimFloatTexture(mOwner.recoloredStack(level).width(), mOwner.recoloredStack(level).height(), mOwner.recoloredStack(level).numComp()); int w = level_4D.getWidth(); int h = level_4D.getHeight(); Globals.Assert(w == mOwner.stack(level).getWidth() && h == mOwner.stack(level).height()); Globals.Assert(level_4D.numComp() == Globals.NUM_RECOLORED_PCA_COMPONENTS); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { // . copy first four channels for (int c = 0; c < 4; c++) { level_4D.set(mOwner.recoloredStack(level).get(i, j, c), i, j, c); } // . zero out all channels above 4 for (int c = 4; c < level_4D.numComp(); c++) { level_4D.set(0, i, j, c); } } } recolored_level = level_4D; } else { // . keep all dimensions recolored_level = mOwner.recoloredStack(level); } m_SynthNeighborhoods[level] = new NeighborhoodSynth[recolored_level.width() * recolored_level.height()]; stack_accessor_v2 access = new stack_accessor_v2(level); for (int j = 0; j < recolored_level.height(); j++) { for (int i = 0; i < recolored_level.width(); i++) { int index = i + j * recolored_level.width(); m_SynthNeighborhoods[level][index] = new NeighborhoodSynth(); m_SynthNeighborhoods[level][index].construct( recolored_level, access, (!mOwner.isToroidal()) && level < (mNumLevels - Globals.NUM_LEVELS_WITHOUT_BORDER), //(!m_bToroidal) && l < FIRST_LEVEL_WITH_BORDER, level, i, j); } } } tm.destroy(); tm = null; }