aboutsummaryrefslogtreecommitdiff
path: root/src/kernel.c
diff options
context:
space:
mode:
authorallusive-dev <[email protected]>2023-10-30 15:12:21 +1100
committerallusive-dev <[email protected]>2023-10-30 15:12:21 +1100
commitac33357e7ce7c474aeaffc92e381020289d767a2 (patch)
tree7f05fa79b3ccd7834f85cc65a07fbd4f8030eb94 /src/kernel.c
parentCreate FUNDING.yml (diff)
downloadcompfy-ac33357e7ce7c474aeaffc92e381020289d767a2.tar.xz
compfy-ac33357e7ce7c474aeaffc92e381020289d767a2.zip
Version 1.01.0.0
Diffstat (limited to 'src/kernel.c')
-rw-r--r--src/kernel.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/kernel.c b/src/kernel.c
index 5151045..cbb5cd1 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -90,15 +90,20 @@ conv *gaussian_kernel(double r, int size) {
/// Estimate the element of the sum of the first row in a gaussian kernel with standard
/// deviation `r` and size `size`,
static inline double estimate_first_row_sum(double size, double r) {
+ // `factor` is integral of gaussian from -size to size
double factor = erf(size / r / sqrt(2));
+ // `a` is gaussian at (size, 0)
double a = exp(-0.5 * size * size / (r * r)) / sqrt(2 * M_PI) / r;
+ // The sum of the whole kernel is normalized to 1, i.e. each element is divided by
+ // factor sqaured. So the sum of the first row is a * factor / factor^2 = a /
+ // factor
return a / factor;
}
-/// Pick a suitable gaussian kernel radius for a given kernel size. The returned radius
-/// is the maximum possible radius (<= size*2) that satisfies no sum of the rows in
-/// the kernel are less than `row_limit` (up to certain precision).
-static inline double gaussian_kernel_std_for_size(int size, double row_limit) {
+/// Pick a suitable gaussian kernel standard deviation for a given kernel size. The
+/// returned radius is the maximum possible radius (<= size*2) that satisfies no sum of
+/// the rows in the kernel are less than `row_limit` (up to certain precision).
+double gaussian_kernel_std_for_size(double size, double row_limit) {
assert(size > 0);
if (row_limit >= 1.0 / 2.0 / size) {
return size * 2;
@@ -121,14 +126,14 @@ static inline double gaussian_kernel_std_for_size(int size, double row_limit) {
/// transparent, so the transition from shadow to the background is smooth.
///
/// @param[in] shadow_radius the radius of the shadow
-conv *gaussian_kernel_autodetect_deviation(int shadow_radius) {
+conv *gaussian_kernel_autodetect_deviation(double shadow_radius) {
assert(shadow_radius >= 0);
- int size = shadow_radius * 2 + 1;
+ int size = (int)(shadow_radius * 2 + 1);
if (shadow_radius == 0) {
return gaussian_kernel(0, size);
}
- double std = gaussian_kernel_std_for_size(shadow_radius, 1.0 / 256.0);
+ double std = gaussian_kernel_std_for_size(shadow_radius, 0.5 / 256.0);
return gaussian_kernel(std, size);
}