// This function actually applies the specified noise to the given image // in the given amounts IplImage* GenerateNoise(IplImage* img, int noiseType, float amount=255) { CvSize imgSize = cvGetSize(img); IplImage* imgTemp = cvCloneImage(img); // This will hold the noisy image // Go through each pixel for(int y=0;y<imgSize.height;y++) { for(int x=0;x<imgSize.width;x++) { int randomValue=0; // Our noise is additive.. this holds switch(noiseType) // the amount to add/subtract { case NOISE_UNIFORM: // I chose UNIFORM, so give me a uniform random number randomValue = (char)(uniform()*amount); break; case NOISE_EXPONENTIAL: // I chose EXPONENTIAL... so exp random number please randomValue = (int)(exponential()*amount); break; case NOISE_GAUSSIAN: // same here randomValue = (int)(gaussian()*amount); break; case NOISE_RAYLEIGH: // ... guess!! randomValue = (int)(rayleigh()*amount); break; case NOISE_GAMMA: // I chose gamma... give me a gamma random number randomValue = (int)(gamma()*amount); break; case NOISE_IMPULSE: // I need salt and pepper.. pass the shakers please randomValue = (int)(impulse((float)amount/256)*amount); } // Here we "apply" the noise to the current pixel int pixelValue = cvGetReal2D(imgTemp, y, x)+randomValue; // And set this value in our noisy image cvSetReal2D(imgTemp, y, x, pixelValue); } } // return return imgTemp; }
// This function actually applies the specified noise to the given // in the given amounts IplImage* GenerateNoise(IplImage* img, int noiseType, float amount=255) { CvSize imgSize = cvGetSize(img); IplImage* imgTemp = cvCloneImage(img); // This will hold the n // Go through each pixel for(int y=0; y<imgSize.height; y++) { for(int x=0; x<imgSize.width; x++) { int randomValue=0; // our noise is additivwe switch(noiseType) // the amount to add/substract { case NOISE_UNIFORM: randomValue = (char)(uniform()*amount); break; case NOISE_EXPONENTIAL: randomValue = (int)(exponential()*amount); break; case NOISE_GAUSSIAN: randomValue = (int)(gaussian()*amount); break; case NOISE_RAYLEIGH: randomValue = (int)(rayleigh()*amount); break; case NOISE_GAMMA: break; case NOISE_IMPULSE: randomValue = (int)(impulse((float)amount/256)*amount); } int pixelValue = cvGetReal2D(imgTemp, y, x)+randomValue; // And set this value in our noisy image cvSetReal2D(imgTemp, y, x, pixelValue); } } // return return imgTemp; }
Colorf Sky::getRadianceAt(float theta, float phi, bool checkerboard) { if(checkerboard) { const int x = theta / (pi / 5); const int y = phi / (pi / 5); const int parity = (x ^ y) % 2; const float val = parity ? 150 : 100; return Colorf(val, val, val); } if(theta > pi / 2) { return Colorf(0, 0, 0); } // Preetham sky model // http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf // // Hints for reading the paper: // * we don't consider object light scattering // (maybe needed later when considering far-away moutains or such) // * when there's no object, L(0) = 0 (universe background) // * don't get distracted by approximations for hand-calculation // (it's simpler (and more flexible) to do numerical calc + smart memoization) const float view_height = 0; const float alpha_haze = 0.8333; // haze: /km const float alpha_mole = 0.1136; // molecules: /km const Eigen::Vector3f view_direction( std::sin(theta) * std::cos(phi), std::sin(theta) * std::sin(phi), std::cos(theta)); // Based on Nishita's 1st-order scattering sky model. // We ignore point-to-space decay. Colorf radiance(0, 0, 0); Colorf decay_here_to_view(1, 1, 1); for(int i = 0; i < 50; i++) { const float distance = i; const float height = distance * std::cos(theta) + view_height; // const float cos_view_sun = view_direction.dot(sun_direction); // Calculate scattering // Mie scattering's phase function is not well-described anywhere. // But it's said to be very sharp. So // we use (1+cos^3 theta)^2/4 // (http://www.wolframalpha.com/input/?i=plot+r%3D%281%2Bcos%5E3+theta%29%5E2%2F4) const Colorf scatter = particleDensity(alpha_mole, distance, theta) * rayleigh(cos_view_sun) + particleDensity(alpha_haze, distance, theta) * mie(cos_view_sun); // Note. decay_space_to_here and decay_here_to_view are not colinear. radiance += sun_power .cwiseProduct(scatter) .cwiseProduct(decay_here_to_view); const Colorf decay_scatter = particleDensity(alpha_mole, distance, theta) * rayleighTotal() + particleDensity(alpha_haze, distance, theta) * mieTotal(); decay_here_to_view = decay_here_to_view.cwiseProduct( Colorf(1, 1, 1) - decay_scatter); } assert(radiance[0] >= 0 && radiance[1] >= 0 && radiance[2] >= 0); radiance /= 100; return radiance; }
Colorf Sky::rayleigh(float cos) { return Colorf( rayleigh(cos, wl_r), rayleigh(cos, wl_g), rayleigh(cos, wl_b)); }