Last active
October 19, 2020 20:10
-
-
Save jedypod/39466f284d53e6840e19ff60973581d7 to your computer and use it in GitHub Desktop.
Perform a spatially varying box blur based on an input map. Box blur only for the moment. Uses a summed area table.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* iBlur - Compute a box-blur based on a control image input. | |
Requires a Summed Area Table input. | |
*/ | |
kernel iBlur : ImageComputationKernel<eComponentWise> { | |
Image<eRead, eAccessPoint, eEdgeClamped> src; | |
Image<eRead, eAccessPoint, eEdgeClamped> ctr; | |
Image<eRead, eAccessRandom, eEdgeClamped> sat; | |
Image<eWrite> dst; | |
param: | |
float2 size; | |
local: | |
void init() { | |
} | |
// Find Summed Area Table sum given point p and radius r (box of size 2*r+1) | |
float satsum(float2 p, float2 r) { | |
float d = bilinear(sat, p.x+r.x, p.y+r.y); | |
float b = bilinear(sat, p.x+r.x, p.y-r.y-1); | |
float c = bilinear(sat, p.x-r.x-1, p.y+r.y); | |
float a = bilinear(sat, p.x-r.x-1, p.y-r.y-1); | |
return d-b-c+a; | |
} | |
void process(int2 p) { | |
// Blur size using ctr input as multiplier | |
float2 s = float2(ctr()*size.x, ctr()*size.y); | |
// Don't process if size is small | |
if (s.x<1e-8&&s.y<1e-8) { dst() = src(); return; } | |
// Normalization factor | |
float norm = (s.x*2.0f+1)*(s.y*2.0f+1); | |
// Get sum from SAT | |
float sum = satsum(float2(p.x, p.y), s); | |
// Write normalized sum to output | |
dst() = sum/norm; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Create a summed area table in one direction, based on an input image. | |
In order to create a 2-dimensional summed area table, | |
you need two copies of the node, the 2nd with col=true | |
Currently there are issues with precision for higher resolution images... | |
*/ | |
kernel SummedAreaTable : ImageComputationKernel<eComponentWise> { | |
Image<eRead, eAccessRandom, eEdgeConstant> src; | |
Image<eReadWrite, eAccessRandom> dst; | |
param: | |
bool col; | |
local: | |
int n; | |
void init() { | |
n = col?src.bounds.height():src.bounds.width(); | |
} | |
void process(int2 p) { | |
if (col?p.y>0:p.x>0) return; | |
dst(col?p.x:0, col?0:p.y) = src(col?p.x:0, col?0:p.y); | |
for (int i=1; i<n; i++) | |
dst(col?p.x:i, col?i:p.y) = src(col?p.x:i, col?i:p.y) + dst(col?p.x:i-1, col?i-1:p.y); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment