/** * Get the standard deviation (sigma) of an image only using values clipped by 3*sigma from a * first estimate of sigma * * @param img input image * @return 3*sigma clipped std dev */ protected double get3SigClippedStdDev(MTBImage img) { int sizeStack = img.getSizeStack(); int sizeX = img.getSizeX(); int sizeY = img.getSizeY(); double val; double mu = 0.0; double mu2 = 0.0; double N = 0.0; double sigma; for (int i = 0; i < sizeStack; i++) { img.setCurrentSliceIndex(i); for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++) { val = img.getValueDouble(x, y); mu += val; mu2 += val * val; N++; } } } mu /= N; mu2 /= N; sigma = Math.sqrt(mu2 - mu * mu); mu = 0.0; mu2 = 0.0; N = 0.0; for (int i = 0; i < sizeStack; i++) { img.setCurrentSliceIndex(i); for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++) { val = img.getValueDouble(x, y); if (Math.abs(val - mu) <= 3.0 * sigma) { mu += val; mu2 += val * val; N++; } } } } img.setCurrentSliceIndex(0); mu /= N; mu2 /= N; sigma = Math.sqrt(mu2 - mu * mu); return sigma; }
/** * Denoise wavelet coefficients using Jeffrey's noninformative prior for a given sigma of noise * * @param img input image * @param sigma sigma of noise */ protected void denoise(MTBImage img, double sigma) { int sizeStack = img.getSizeStack(); int sizeX = img.getSizeX(); int sizeY = img.getSizeY(); double s2 = 3.0 * sigma * sigma; double val, val2; for (int i = 0; i < sizeStack; i++) { img.setCurrentSliceIndex(i); for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++) { val = img.getValueDouble(x, y); val2 = (val * val - s2); if (val2 < 0.0) val2 = 0.0; if (val != 0.0) img.putValueDouble(x, y, val2 / val); else img.putValueDouble(x, y, 0.0); } } } img.setCurrentSliceIndex(0); }