#include #include "bloom.h" Bloom::Bloom(CImg image) : image(image) {} CImg Bloom::bloom(float threshold, int kernelSize, float sigma, float intensity) { // Apply threshold to image //CImg brightPixels = image_.get_threshold(threshold); //brightPixels.save("brightpixels.png"); // Apply gaussian blur to bright pixels CImg kernel = computeGaussianKernel(kernelSize, sigma); CImg blurred = convolution(image, kernel); for(int i = 0; i < 3; i++){ kernel = computeGaussianKernel(kernelSize, sigma); blurred = convolution(image, kernel); blurred *= intensity; } // Add blurred image back to original image cimg_forXYC(image, x, y, c) { float value = image(x,y,0,c) + blurred(x,y,0,c); image(x,y,0,c) = (value > 1.0f) ? 1.0f : value; } return image; } void Bloom::gaussianBlur(int kernelSize, float sigma) { CImg kernel = computeGaussianKernel(kernelSize, sigma); image = convolution(image, kernel); } // Function to compute Gaussian kernel CImg Bloom::computeGaussianKernel(int kernelSize, float sigma) { // Create kernel CImg kernel(kernelSize, kernelSize, 1, 1); // Compute Gaussian kernel float sum = 0.0f; int i, j; for (i = 0; i < kernelSize; i++) { for (j = 0; j < kernelSize; j++) { kernel(i, j) = exp(-0.5f * (pow((i - kernelSize / 2.f) / sigma, 2.f) + pow((j - kernelSize / 2.f) / sigma, 2.f))) / (2 * M_PI * sigma * sigma); sum += kernel(i, j); } } // Normalize kernel kernel /= sum; return kernel; } // Function to perform convolution CImg Bloom::convolution(CImg &img, CImg &kernel) { int kernelSize = kernel.width(); int imgRows = img.height(); int imgCols = img.width(); CImg result(imgCols, imgRows, 1, 3); float sum; int i, j, m, n; int kernelRadius = kernelSize / 2; // Perform convolution cimg_forXYC(img, i, j, c) { sum = 0; cimg_forY(kernel, m) { cimg_forX(kernel, n) { int x = i + n - kernelRadius; int y = j + m - kernelRadius; if(x >= 0 && x < imgCols && y >= 0 && y < imgRows){ sum += img(x, y, 0, c) * kernel(n, m); } } } result(i, j, 0, c) = sum; } return result; } void Bloom::scaleBrightness(float scale) { image *= scale; }