Skip to content

Instantly share code, notes, and snippets.

@jedypod
Last active October 19, 2020 20:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedypod/39466f284d53e6840e19ff60973581d7 to your computer and use it in GitHub Desktop.
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.
/* 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;
}
};
/* 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