Minetest-WorldEditAdditions/worldeditadditions/lib/conv/kernel_gaussian.lua

53 lines
1.7 KiB
Lua
Raw Permalink Normal View History

2022-09-19 00:16:22 +00:00
local wea_c = worldeditadditions_core
-- Ported from Javascript by Starbeamrainbowlabs
-- Original source: https://github.com/sidorares/gaussian-convolution-kernel/
-- From
-- the code is taken from https://github.com/mattlockyer/iat455/blob/6493c882f1956703133c1bffa1d7ee9a83741cbe/assignment1/assignment/effects/blur-effect-dyn.js
-- (c) Matt Lockyer, https://github.com/mattlockyer
-- hypotenuse has moved to utils/numbers.lua
--[[
* Generates a kernel used for the gaussian blur effect.
*
* @param dimension is an odd integer
* @param sigma is the standard deviation used for our gaussian function.
*
* @returns an array with dimension^2 number of numbers, all less than or equal
* to 1. Represents our gaussian blur kernel.
]]--
function worldeditadditions.conv.kernel_gaussian(dimension, sigma)
if not (dimension % 2) or math.floor(dimension) ~= dimension or dimension < 3 then
return false, "The dimension must be an odd integer greater than or equal to 3"
end
local kernel = {};
local two_sigma_square = 2 * sigma * sigma;
local centre = (dimension - 1) / 2;
local sum = 0
for i = 0, dimension-1 do
for j = 0, dimension-1 do
2022-09-19 00:16:22 +00:00
local distance = wea_c.hypotenuse(i, j, centre, centre)
-- The following is an algorithm that came from the gaussian blur
-- wikipedia page [1].
--
-- http://en.wikipedia.org/w/index.php?title=Gaussian_blur&oldid=608793634#Mechanics
local gaussian = (1 / math.sqrt(
math.pi * two_sigma_square
2022-09-18 15:30:27 +00:00
)) * math.exp((-1) * ((distance ^ 2) / two_sigma_square));
sum = sum + gaussian
kernel[i*dimension + j] = gaussian
end
end
-- Returns the unit vector of the kernel array.
for k,v in pairs(kernel) do
kernel[k] = kernel[k] / sum
end
return true, kernel
end