kernel Brighten < namespace : "micron_developers"; vendor : "micron_developers"; version : 1; description : "Brights up an image based on high luminance pixels"; > { parameter float factor < minValue: float(0.0); maxValue: float(2.0); defaultValue: float(0.85); >; parameter float bright < minValue: float(1.0); maxValue: float(4.0); defaultValue: float(1.5); >; parameter float power < minValue: float(0.0); maxValue: float(5.0); defaultValue: float(4.4); >; parameter float acctweak < minValue: float(0.0); maxValue: float(5.0); defaultValue: float(1.3); >; parameter int rings < minValue: int(1); maxValue: int(5); defaultValue: int(4); >; parameter float radius < minValue: float(1.0); maxValue: float(15.0); defaultValue: float(3.0); >; // ring weights dependent float w1, w2, w3, w4, w5; input image4 src; output pixel4 dst; void evaluateDependents() { w1 = 10.1; w2 = 6.75; w3 = 4.5; w4 = 3.0; w5 = 2.0; } // customizable "luminance" function float lum(float4 s) { return (s.r + s.g + s.b)/3.0; } // evaluates the accumulation contribution float4 evalAcc(float4 s) { float l = lum(s); return s*pow(l*bright, acctweak); } // evaluatePixel void evaluatePixel() { float4 s = sampleNearest(src, outCoord()); float h = lum(s); // find contribution from other pixels float4 acc = float4(0.0); float4 acc1 = float4(0.0), acc2 = float4(0.0), acc3 = float4(0.0), acc4 = float4(0.0), acc5 = float4(0.0); float w = 0.00001; if (rings > 0) { acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-1.0, -1.0))); acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-1.0, 0.0))) * 2.0; acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-1.0, 1.0))); acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, -1.0))) * 2.0; acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, 1.0))) * 2.0; acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(1.0, -1.0))); acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(1.0, 0.0))) * 2.0; acc1 += evalAcc(sampleNearest(src, outCoord() + radius*float2(1.0, 1.0))); acc1 /= 12.0; acc1 *= w1; w += w1; } if (rings > 1) { acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-2.0, -2.0))); acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-2.0, 0.0))) * 2.0; acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-2.0, 2.0))); acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, -2.0))) * 2.0; acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, 2.0))) * 2.0; acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(2.0, -2.0))); acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(2.0, 0.0))) * 2.0; acc2 += evalAcc(sampleNearest(src, outCoord() + radius*float2(2.0, 2.0))); acc2 /= 12.0; acc2 *= w2; w += w2; } if (rings > 2) { acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-3.0, -3.0))); acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-3.0, 0.0))) * 2.0; acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-3.0, 3.0))); acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, -3.0))) * 2.0; acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, 3.0))) * 2.0; acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(3.0, -3.0))); acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(3.0, 0.0))) * 2.0; acc3 += evalAcc(sampleNearest(src, outCoord() + radius*float2(3.0, 3.0))); acc3 /= 12.0; acc3 *= w3; w += w3; } if (rings > 3) { acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-4.0, -4.0))); acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-4.0, 0.0))) * 2.0; acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-4.0, 4.0))); acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, -4.0))) * 2.0; acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, 4.0))) * 2.0; acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(4.0, -4.0))); acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(4.0, 0.0))) * 2.0; acc4 += evalAcc(sampleNearest(src, outCoord() + radius*float2(4.0, 4.0))); acc4 /= 12.0; acc4 *= w4; w += w4; } if (rings > 4) { acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-5.0, -5.0))); acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-5.0, 0.0))) * 2.0; acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(-5.0, 5.0))); acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, -5.0))) * 2.0; acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(0.0, 5.0))) * 2.0; acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(5.0, -5.0))); acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(5.0, 0.0))) * 2.0; acc5 += evalAcc(sampleNearest(src, outCoord() + radius*float2(5.0, 5.0))); acc5 /= 12.0; acc5 *= w5; w += w5; } // aggregate acc acc = (acc1+acc2+acc3+acc4+acc5)/w; // account pixel luminance acc *= pow(h, 5.0-power); // overall factor acc *= factor; // add dst = s+acc; } }