Blur Parts of Camera Feed Keeping Others in Focus

I’m building an app that displays a live camera video feed onto a standard display. I’m trying to keep a centered square portion of the video in focus while blurring out the top, bottom, left, and right of the video.

I’ve looked at some threads that seem to be trying to solve more complicated problems than this. And I’ve experimented with applying textures but haven’t been able to crack this yet.

I’ve done this in Processing by drawing a filter, and then looping through a set of pixels and unblurring them. It works, but the performance is horrific, even before the undoing of the blur, so that’s why I’m here. I have some experience with OF but these notions of textures, shaders, etc, are somewhat new to me. I’m totally fine when it comes to actually writing the code, but I’m struggling to come up with an approach to solving this problem.

Any help/advice is much appreciated.

I would grab these tutorial files from the oF github, this is how I got myself started with shaders:

https://github.com/openframeworks/openFrameworks/tree/master/tutorials/shader

check out the last one in particular (although you should go in order if you haven’t worked with shaders before). If you can rewrite a blur filter like that last tut so that it ignores your chosen area in the center, and then maybe blurs outwards from there towards the edges of the screen… is that close to the effect that you’re imagining?

I think if you handle it that way, you can do the following:

ofImage cam_image;
ofFbo output_image;
ofShader blur_thing;

do something like :

output_image.begin();
ofClear(ofColor::white);
blur_thing.begin();
blur_thing.setUniformTexture(“tex0”, cam_image.getTextureReference(),0);
ofRect(0, 0, cam_image.width, cam_image.height);
blur_thing.end();
output_image.end();

then:

draw() {
output_image.draw();
}

inside the shader you could do a check againt the gl_FragCoord?

ie.

vec2 tCoord = gl_FragCoord.xy;

if((tCoord.x < xMin || tCoord.x > xMax) && (tCoord.y < yMin || tCoord.y > yMax)) {
(do some blurring here… steal from the gaussian blur example, but will probably need to tweak it)
}

Yes, that’s exactly the effect I’m going for. I did look at some shader source code, and it seems like the shader is applied to the whole display area. How would I selectively apply a shader to a set of pixels?

oops, was rewriting my first reply… look up ^^^

That makes sense. Thanks!

Or for a more customised area, you can create a blur of the whole frame and use an alpha mask to blend it with the original. You can draw the alpha mask and give it soft edges as well.

1 Like

That totally worked. Thank you so much!