88 lines
2.5 KiB
C++
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;
|
|
}
|