Esempio n. 1
0
void CrossNLMFilter::Apply(
                  float sigmaR,
                  const vector<TwoDArray<float> > &mseArray,
                  const vector<TwoDArray<float> > &priArray,
                  const TwoDArray<Color> &rImg,
                  const TwoDArray<Feature> &featureImg,
                  const TwoDArray<Feature> &featureVarImg,
                  vector<TwoDArray<float> > &outMSE,
                  vector<TwoDArray<float> > &outPri) const {
    float mseScaleR = -0.5f/(sigmaR*sigmaR);
#pragma omp parallel for num_threads(PbrtOptions.nCores) schedule(static)   
    for(int taskId = 0; taskId < nTasks; taskId++) {
        int txs, txe, tys, tye;
        ComputeSubWindow(taskId, nTasks, width, height,
                         &txs, &txe, &tys, &tye); 
        for(int y = tys; y < tye; y++) 
            for(int x = txs; x < txe; x++) { 
                vector<float> mseSum(mseArray.size(), 0.f);
                vector<float> priSum(priArray.size(), 0.f);
                vector<float> wSum(mseArray.size(), 0.f);
                Feature feature = featureImg(x, y);
                Feature featureVar = featureVarImg(x, y);            
 
                // Filter using pixels within search range
                for(int dy = -searchRadius; dy <= searchRadius; dy++)
                    for(int dx = -searchRadius; dx <= searchRadius; dx++) {
                        int xx = x + dx;
                        int yy = y + dy;
                        if(xx < 0 || yy < 0 || xx >= width || yy >= height) 
                            continue;
                        Color diffSqSum(0.f, 0.f, 0.f);
                        // Calculate block distance
                        for(int by = -patchRadius; by <= patchRadius; by++)
                            for(int bx = -patchRadius; bx <= patchRadius; bx++) {
                                int xbx = x + bx;
                                int yby = y + by;
                                int xxbx = xx + bx;
                                int yyby = yy + by;
                                if( xbx < 0 || xbx >= width ||
                                    yby < 0 || yby >= height ||
                                    xxbx < 0 || xxbx >= width ||
                                    yyby < 0 || yyby >= height)
                                    continue;

                                Color diff = rImg(xbx, yby) - rImg(xxbx, yyby);
                                diffSqSum += (diff*diff);
                            }
                        diffSqSum *= invPatchSize;
                        float dist = Avg(diffSqSum);
                        Feature fDiff = feature - featureImg(xx, yy);                    
                        Feature fVarSum = featureVar + featureVarImg(xx, yy);
                        Feature fDist = (fDiff*fDiff)/fVarSum.Max(c_VarMax);
                        float weight = fmath::exp(dist*mseScaleR +
                                                  Sum(fDist*scaleF)); 
                        for(size_t i = 0; i < mseArray.size(); i++) {
                            mseSum[i] += weight * mseArray[i](xx, yy);
                            priSum[i] += weight * priArray[i](xx, yy);
                            wSum[i] += weight;
                        }
                    }                

                for(size_t i = 0; i < mseArray.size(); i++) {
                    outMSE[i](x, y) = mseSum[i] / wSum[i];
                    outPri[i](x, y) = priSum[i] / wSum[i];
                }
            }            
    }   

}
Esempio n. 2
0
void CrossNLMFilter::Apply(const TwoDArray<Color> &img,
               const TwoDArray<Feature> &featureImg,
               const TwoDArray<Feature> &featureVarImg,
               const TwoDArray<Color> &rImg,
               const TwoDArray<Color> &varImg,
               vector<TwoDArray<Color> > &fltArray,
               vector<TwoDArray<float> > &mseArray,
               vector<TwoDArray<float> > &priArray) const {    
#pragma omp parallel for num_threads(PbrtOptions.nCores) schedule(static)   
    for(int taskId = 0; taskId < nTasks; taskId++) {
        int txs, txe, tys, tye;
        ComputeSubWindow(taskId, nTasks, width, height,
                         &txs, &txe, &tys, &tye); 
        for(int y = tys; y < tye; y++) 
            for(int x = txs; x < txe; x++) { 
                vector<Color> sum(scaleR.size(), Color(0.f));
                vector<Color> rSum(scaleR.size(), Color(0.f));
                vector<Color> rSumSq(scaleR.size(), Color(0.f));
                vector<float> wSum(scaleR.size(), 0.f);
                vector<vector<float> > wArray(scaleR.size());
                for(size_t p = 0; p < wArray.size(); p++) {
                    wArray[p].resize(patchWidth*patchWidth);
                }
                Feature feature = featureImg(x, y);
                Feature featureVar = featureVarImg(x, y);            
 
                // Filter using pixels within search range
                for(int dy = -searchRadius; dy <= searchRadius; dy++)
                    for(int dx = -searchRadius; dx <= searchRadius; dx++) {
                        int xx = x + dx;
                        int yy = y + dy;
                        if(xx < 0 || yy < 0 || xx >= width || yy >= height) 
                            continue;
                        Color diffSqSum(0.f, 0.f, 0.f);
                        // Calculate block distance
                        for(int by = -patchRadius; by <= patchRadius; by++)
                            for(int bx = -patchRadius; bx <= patchRadius; bx++) {
                                int xbx = x + bx;
                                int yby = y + by;
                                int xxbx = xx + bx;
                                int yyby = yy + by;
                                if( xbx < 0 || xbx >= width ||
                                    yby < 0 || yby >= height ||
                                    xxbx < 0 || xxbx >= width ||
                                    yyby < 0 || yyby >= height)
                                    continue;

                                Color diff = rImg(xbx, yby) - rImg(xxbx, yyby);
                                diffSqSum += (diff*diff);
                            }
                        diffSqSum *= invPatchSize;
                        float dist = Avg(diffSqSum);
                        Feature fDiff = feature - featureImg(xx, yy);                    
                        Feature fVarSum = featureVar + featureVarImg(xx, yy);
                        Feature fDist = (fDiff*fDiff)/fVarSum.Max(c_VarMax);
                        // For each parameter, calculate information necessary for 
                        // filtering and SURE estimation
                        for(size_t p = 0; p < scaleR.size(); p++) {
                            if(scaleR[p] == 0.f) {
                                continue;
                            }
                            float weight = fmath::exp(dist*scaleR[p] +
                                                      Sum(fDist*scaleF));
                            sum[p] += weight * img(xx, yy);
                            rSum[p] += weight * rImg(xx, yy);
                            rSumSq[p] += weight * rImg(xx, yy) * rImg(xx, yy);
                            wSum[p] += weight;
                            if(dy >= -patchRadius && dy <= patchRadius &&
                               dx >= -patchRadius && dx <= patchRadius) {
                                wArray[p][(dy+patchRadius)*patchWidth+(dx+patchRadius)] =
                                    weight;
                            }
                        }
                    }                

                for(size_t p = 0; p < scaleR.size(); p++) {
                    if(scaleR[p] == 0.f) {
                        fltArray[p](x, y) = img(x, y);
                        mseArray[p](x, y) = Avg(2.f*varImg(x, y));
                        continue;
                    }
                    float invWSum = 1.f/wSum[p];
                    Color xl    = sum[p] * invWSum;
                    Color rxl   = rSum[p] * invWSum;
                    Color rxlSq = rSumSq[p] * invWSum;
                    Color ryl   = rImg(x, y);
                    Color dxdy  = (-2.f*scaleR[p])*(rxlSq - rxl*rxl)*invPatchSize + Color(invWSum);

                    Color tmp;
                    for(int by = -patchRadius; by <= patchRadius; by++)
                        for(int bx = -patchRadius; bx <= patchRadius; bx++) {
                            int xbpx = x+bx;
                            int ybpy = y+by;
                            int xbmx = x-bx;
                            int ybmy = y-by;                        
                            if( xbpx < 0 || xbpx >= width  ||
                                ybpy < 0 || ybpy >= height ||
                                xbmx < 0 || xbmx >= width  ||
                                ybmy < 0 || ybmy >= height)
                                continue;
                            Color rylpb = rImg(xbpx, ybpy);
                            Color rylmb = rImg(xbmx, ybmy);
                            float w = wArray[p][(-by+patchRadius)*patchWidth+(-bx+patchRadius)];
                            tmp += w*(ryl - rylpb)*(rxl - rylmb);
                        }
                    tmp *= (-2.f*scaleR[p])*invPatchSize*invWSum;
                    dxdy += tmp;
                    Color mse = (rxl-ryl)*(rxl-ryl) + 2.f*varImg(x, y)*dxdy - varImg(x, y);
                    Color pri = (mse + varImg(x, y));
                    fltArray[p](x, y) = xl;
                    mseArray[p](x, y) = Avg(mse);
                    priArray[p](x, y) = Avg(pri) / (xl.Y()*xl.Y() + 1e-2f);
                } 
            }            
    }
}