Kernel (convolution matrix) on an ofImage

Hi! Is there a way to apply a convolution matrix on an ofImage? I know I can do it manually iterating through all the pixels of the image, but it would be nice to do something like:

//h
ofImage image;

// setup
image.load("image.png");
int convolutionMatrix[3][3] = {{1,1,1}, {1,-1,1}, {1,1,1}};
image.applyMatrix(convolutionMatrix);

//draw
image.draw(0, 0);

Is there something like this? Thank you

I’ve seen there’s a similar question from 2015 without answer: How to aplly a kernel to an ofImage? - #3 by micuat.

hi! I think my post you referred to is close to an answer. ofImage is usually for rendering and not for complex filter operations. You need to use libraries such as ofxCv (opencv) to achieve, for example, convolution.

1 Like

Hey just to add to micuat’s post, there are a few options. ofxCv (and the openCV libs) have tons of functions and types for working with images. I guessing, but I think these work on the cpu side of the hardware. You may also be able to find an existing addon from the oF community (ofxPostProcessing comes to mind). And then if you have a gpu and need to apply the convolution to lots of images (say video or an animation), you could use an ofShader (maybe along with a pair of ofFbo for reading and writing, depending).

1 Like

You can use the built-in openCv Addon or, easier, use ofxCv to send pixels through the opencv filter2d function.

https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#ga27c049795ce870216ddfb366086b5a04

I’m sure there are other examples, but you can find a way to convert between a cv::Mat and ofImage / ofPixels in an example like this ofxCv/ofApp.h at master · kylemcdonald/ofxCv · GitHub

If you’re using ofxDlib for some reason, you can do a similar toll-free operation using the dlib::conv function (here). Examples of how to convert between dlib and of formats are here.

1 Like

Depending on how you have opencv / dlib compiled, convolution / filter2d operations will be hardware accelerated on the CPU.

Hey I was kinda wondering about that, so that’s good to know! I’m not sure how to enable that (for say a linux desktop with either integrated graphics or a video card), but I’ll bet the internet could be of some help. Maybe its enabled by default, depending on the hardware configuration?

Dlib uses flags like these: ofxDlib/dlib.sh at develop · bakercp/ofxDlib · GitHub I’m not sure if OF compiles openCV with optimizations by default.

We compile opencv with the following flags on osx

For linux, it uses whatever flags are available from the package manager.

You can learn more about the optimization flags here

1 Like

Hello @bakercp,

what do you mean?

isn’t cuda acceleration needed for that?
with flags such as :


-D WITH_CUDA=ON -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1-D CUDNN_LIBRARY=/usr/local/cuda/lib64/libcudnn.so.8 -D CUDA_ARCH_BIN="6.0,6.1"

I understand the flags have to be constructed for each platform and cuda Arch bin has to be created for each specific Graphic’s card ( Arnon Shimoni 's article on it) , which makes even more specific.

1 Like

Sorry, I should have said “parallelized” or “Optimized” on the CPU via SIMD instructions, rather than accelerated. Basically, if available, both dlib and opencv will use SIMD calls for convolution on the CPU. Convolution on the GPU is also parallel, but when working with ofPixels in RAM staying on the CPU might be faster / easier.

1 Like

ah yeah right i was wondering about it.
Thanks for clarifying.

Because kernel convolutions on the GPU are also possible through cuda .cu files, but I’m not sure it would make it faster.

Hey I played around with micuat’s solution a bit today. My test application ran much faster when using an ofImage instead of an ofFloatImage, in case performance is an issue. And passing -1 into the ddepth argument tells cv::filter2D() that the source and destination images have the same depth.

1 Like