cloudy-raytracer/post_processing/bloom.cpp

88 lines
2.5 KiB
C++

#include <iostream>
#include "bloom.h"
Bloom::Bloom(CImg<float> image) : image(image) {}
CImg<float> Bloom::bloom(float threshold, int kernelSize, float sigma, float intensity) {
// Apply threshold to image
//CImg<float> brightPixels = image_.get_threshold(threshold);
//brightPixels.save("brightpixels.png");
// Apply gaussian blur to bright pixels
CImg<float> kernel = computeGaussianKernel(kernelSize, sigma);
CImg<float> 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<float> kernel = computeGaussianKernel(kernelSize, sigma);
image = convolution(image, kernel);
}
// Function to compute Gaussian kernel
CImg<float> Bloom::computeGaussianKernel(int kernelSize, float sigma) {
// Create kernel
CImg<float> 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<float> Bloom::convolution(CImg<float> &img, CImg<float> &kernel) {
int kernelSize = kernel.width();
int imgRows = img.height();
int imgCols = img.width();
CImg<float> 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;
}