Fix blur radius when using the Fourier method
Fix the formula, adapt old pp3s, and change the maximum blur radius where applicable.
This commit is contained in:
parent
ca329d9013
commit
9b16f407aa
@ -52,21 +52,8 @@ void ImProcFunctions::localContrast(LabImage *lab, float **destination, const rt
|
|||||||
#endif
|
#endif
|
||||||
gaussianBlur(lab->L, buf, width, height, sigma);
|
gaussianBlur(lab->L, buf, width, height, sigma);
|
||||||
} else {
|
} else {
|
||||||
float kr = 1.f;
|
|
||||||
//emprical adjustment between FFTW radius and Gaussainblur
|
|
||||||
//under 50 ==> 10.f
|
|
||||||
//above 400 ==> 1.f
|
|
||||||
if(settings->fftwsigma == false) {//empirical formula
|
|
||||||
float ak = -9.f / 350.f;
|
|
||||||
float bk = 10.f - 50.f * ak;
|
|
||||||
kr = ak * sigma + bk;
|
|
||||||
if(sigma < 50.f) kr = 10.f;
|
|
||||||
if(sigma > 400.f) kr = 1.f;
|
|
||||||
} else {//sigma *= sigma
|
|
||||||
kr = sigma;
|
|
||||||
}
|
|
||||||
//OPENMP disabled
|
//OPENMP disabled
|
||||||
ImProcFunctions::fftw_convol_blur2(lab->L, buf, width, height, kr * sigma, 0, 0);
|
ImProcFunctions::fftw_convol_blur2(lab->L, buf, width, height, sigma, 0, 0);
|
||||||
}
|
}
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for if(multiThread)
|
#pragma omp parallel for if(multiThread)
|
||||||
|
@ -9523,8 +9523,8 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i
|
|||||||
|
|
||||||
/*define the gaussian constants for the convolution kernel*/
|
/*define the gaussian constants for the convolution kernel*/
|
||||||
if (algo == 0) {
|
if (algo == 0) {
|
||||||
n_x = rtengine::RT_PI / (double) bfw; //ipol
|
n_x = rtengine::RT_PI / (double) bfw / std::sqrt(2.); //ipol
|
||||||
n_y = rtengine::RT_PI / (double) bfh;
|
n_y = rtengine::RT_PI / (double) bfh / std::sqrt(2.);
|
||||||
} else if (algo == 1) {
|
} else if (algo == 1) {
|
||||||
n_x = 1.f / bfw; //gauss
|
n_x = 1.f / bfw; //gauss
|
||||||
n_y = 1.f / bfh;
|
n_y = 1.f / bfh;
|
||||||
@ -9547,7 +9547,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i
|
|||||||
|
|
||||||
for (int i = 0; i < bfw; i++)
|
for (int i = 0; i < bfw; i++)
|
||||||
if (algo == 0) {
|
if (algo == 0) {
|
||||||
kern[ i + index] = exp((float)(-radius) * (n_x * i * i + n_y * j * j)); //calculate Gauss kernel Ipol formula
|
kern[ i + index] = exp((float)(-radius * radius) * (n_x * i * i + n_y * j * j)); //calculate Gauss kernel Ipol formula
|
||||||
} else if (algo == 1) {
|
} else if (algo == 1) {
|
||||||
kern[ i + index] = radsig * exp((float)(-(n_x * i * i + n_y * j * j) / (2.f * radius * radius))); //calculate Gauss kernel with Gauss formula
|
kern[ i + index] = radsig * exp((float)(-(n_x * i * i + n_y * j * j) / (2.f * radius * radius))); //calculate Gauss kernel with Gauss formula
|
||||||
}
|
}
|
||||||
@ -9585,7 +9585,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i
|
|||||||
int index = j * bfw;
|
int index = j * bfw;
|
||||||
|
|
||||||
for (int i = 0; i < bfw; i++) {
|
for (int i = 0; i < bfw; i++) {
|
||||||
out[i + index] *= exp((float)(-radius) * (n_x * i * i + n_y * j * j)); //apply Gauss kernel without FFT - some authors says radius*radius but differences with Gaussianblur
|
out[i + index] *= exp((float)(-radius * radius) * (n_x * i * i + n_y * j * j)); //apply Gauss kernel without FFT - some authors says radius*radius but differences with Gaussianblur
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (algo == 1) {
|
} else if (algo == 1) {
|
||||||
|
@ -1314,14 +1314,26 @@ void ImProcFunctions::MSRLocal(int call, int sp, bool fftw, int lum, float** red
|
|||||||
if (settings->fftwsigma == false) { //empirical formula
|
if (settings->fftwsigma == false) { //empirical formula
|
||||||
ImProcFunctions::fftw_convol_blur2(src, out, bfwr, bfhr, (kr * RetinexScales[scale]), 0, 0);
|
ImProcFunctions::fftw_convol_blur2(src, out, bfwr, bfhr, (kr * RetinexScales[scale]), 0, 0);
|
||||||
} else {
|
} else {
|
||||||
ImProcFunctions::fftw_convol_blur2(src, out, bfwr, bfhr, (SQR(RetinexScales[scale])), 0, 0);
|
// FFT blur radius fixed in 5.12, resulting in different
|
||||||
|
// blur amount. Here we preserve the original behavior by
|
||||||
|
// multiplying the original sigma SQR(RetinexScales[scale])
|
||||||
|
// with 2 then taking the square root.
|
||||||
|
const auto gaussianSigma = std::sqrt(2.f) * RetinexScales[scale];
|
||||||
|
ImProcFunctions::fftw_convol_blur2(src, out, bfwr, bfhr, gaussianSigma, 0, 0);
|
||||||
}
|
}
|
||||||
} else { // reuse result of last iteration
|
} else { // reuse result of last iteration
|
||||||
// out was modified in last iteration => restore it
|
// out was modified in last iteration => restore it
|
||||||
if (settings->fftwsigma == false) { //empirical formula
|
if (settings->fftwsigma == false) { //empirical formula
|
||||||
ImProcFunctions::fftw_convol_blur2(out, out, bfwr, bfhr, sqrtf(SQR(kr * RetinexScales[scale]) - SQR(kr * RetinexScales[scale + 1])), 0, 0);
|
ImProcFunctions::fftw_convol_blur2(out, out, bfwr, bfhr, sqrtf(SQR(kr * RetinexScales[scale]) - SQR(kr * RetinexScales[scale + 1])), 0, 0);
|
||||||
} else {
|
} else {
|
||||||
ImProcFunctions::fftw_convol_blur2(out, out, bfwr, bfhr, (SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), 0, 0);
|
// FFT blur radius fixed in 5.12, resulting in different
|
||||||
|
// blur amount. Here we preserve the original behavior by
|
||||||
|
// multiplying the original sigma
|
||||||
|
// SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])
|
||||||
|
// with 2 then taking the square root.
|
||||||
|
const auto gaussianSigma =
|
||||||
|
std::sqrt(2 * (SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])));
|
||||||
|
ImProcFunctions::fftw_convol_blur2(out, out, bfwr, bfhr, gaussianSigma, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10084,6 +10084,40 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
|
|||||||
assignFromKeyfile(keyFile, "Locallab", "shadmaskcie_" + index_str, spot.shadmaskcie, spotEdited.shadmaskcie);
|
assignFromKeyfile(keyFile, "Locallab", "shadmaskcie_" + index_str, spot.shadmaskcie, spotEdited.shadmaskcie);
|
||||||
assignFromKeyfile(keyFile, "Locallab", "LLmaskcieCurvewav_" + index_str, spot.LLmaskciecurvewav, spotEdited.LLmaskciecurvewav);
|
assignFromKeyfile(keyFile, "Locallab", "LLmaskcieCurvewav_" + index_str, spot.LLmaskciecurvewav, spotEdited.LLmaskciecurvewav);
|
||||||
|
|
||||||
|
if (ppVersion < 352) {
|
||||||
|
// FFT Gaussian blur fixed in 5.12. Converts old radii to
|
||||||
|
// the equivalent new radii if FFT mode is enabled. The
|
||||||
|
// fixed blur radius has a factor of radius / 2 compared to
|
||||||
|
// the original, so the base conversion is sqrt(2 * radius).
|
||||||
|
// Derivation: old_radius = new_radius * new_radius / 2
|
||||||
|
// 2 * old_radius = new_radius * new_radius
|
||||||
|
// sqrt(2 * old_radius) = new_radius
|
||||||
|
if (spot.fftColorMask) {
|
||||||
|
spot.blurcol = std::sqrt(2 * spot.blurcol);
|
||||||
|
spotEdited.blurcol = true;
|
||||||
|
}
|
||||||
|
if (spot.fftwbl || spot.radius > 30.) {
|
||||||
|
// Internally, the radius is divided by 1.4, so the
|
||||||
|
// factor is actually radius / 1.4 / 2.
|
||||||
|
spot.radius = std::sqrt(2.8 * spot.radius);
|
||||||
|
spotEdited.radius = true;
|
||||||
|
}
|
||||||
|
if (spot.fftwlc) {
|
||||||
|
// Internally, the radius was squared, so replace
|
||||||
|
// old_radius with old_radius^2 before solving.
|
||||||
|
spot.lcradius = std::sqrt(2.) * spot.lcradius;
|
||||||
|
spotEdited.lcradius = true;
|
||||||
|
}
|
||||||
|
if (spot.fftmask) {
|
||||||
|
spot.blurmask = std::sqrt(2 * spot.blurmask);
|
||||||
|
spotEdited.blurmask = true;
|
||||||
|
}
|
||||||
|
if (spot.fftcieMask) {
|
||||||
|
spot.blurcie = std::sqrt(2 * spot.blurcie);
|
||||||
|
spotEdited.blurcie = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (keyFile.has_key("Locallab", "CSThresholdcie_" + index_str)) {
|
if (keyFile.has_key("Locallab", "CSThresholdcie_" + index_str)) {
|
||||||
const std::vector<int> thresh = keyFile.get_integer_list("Locallab", "CSThresholdcie_" + index_str);
|
const std::vector<int> thresh = keyFile.get_integer_list("Locallab", "CSThresholdcie_" + index_str);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ fft *
|
|||||||
#include "../rtengine/color.h"
|
#include "../rtengine/color.h"
|
||||||
|
|
||||||
#define MINRAD 1.5
|
#define MINRAD 1.5
|
||||||
#define MAXRAD 10000
|
#define MAXRAD 1000
|
||||||
#define CENTERRAD 100
|
#define CENTERRAD 100
|
||||||
#define MINCHRO 0.
|
#define MINCHRO 0.
|
||||||
#define MAXCHRO 150.
|
#define MAXCHRO 150.
|
||||||
|
@ -4660,7 +4660,7 @@ void LocallabContrast::updateContrastGUI3()
|
|||||||
const double temp = lcradius->getValue();
|
const double temp = lcradius->getValue();
|
||||||
|
|
||||||
if (fftwlc->get_active()) {
|
if (fftwlc->get_active()) {
|
||||||
lcradius->setLimits(20, 1000, 1, 80);
|
lcradius->setLimits(20, 1500, 1, 80);
|
||||||
} else {
|
} else {
|
||||||
lcradius->setLimits(20, 100, 1, 80);
|
lcradius->setLimits(20, 100, 1, 80);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes
|
// This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes
|
||||||
#define PPVERSION 351
|
#define PPVERSION 352
|
||||||
#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified
|
#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Log of version changes
|
Log of version changes
|
||||||
|
352 2024-10-27
|
||||||
|
FFT Gaussian blur radius fixed
|
||||||
351 2024-06-19
|
351 2024-06-19
|
||||||
take into account Global in selective editing
|
take into account Global in selective editing
|
||||||
350 2023-03-05
|
350 2023-03-05
|
||||||
|
Loading…
x
Reference in New Issue
Block a user