Combining OpenCV 2.x and Microsoft WPF [w/ code]

Just a quicky about OpenCV and Windows Presentation Framework interoperability. It's really easy with a simple Managed C++ wrapper. What I'll show is how to transfer an OpenCV cv::Mat into WPF's BitmapSource. Let's see how it's done.

First some framework. I'll define a managed C++ (ref) class that holds everything WPF needs to make a BitmapSource:

public ref class OpenCVImageWrapper {
		int width;
		int height;
		cli::array<byte>^ buf;
		int buf_size;
		int row_stride;
		int channels;

That's it, now let's build a BitmapSource out of an instance of this class in C#:

OpenCVImageWrapper im = getFromOpenCV();
BitmapSource bs = BitmapSource.Create(
                im.width, im.height, 96, 96,
                System.Windows.Media.PixelFormats.Bgr24, //need to look out here: this is for BGR 24-bits images, you might need Gray8, Gray32Float or one of others...
                null, im.buf, im.row_stride);
imageOnScreen.Source = bs;

(imageOnScreen is an Image object I dragged and dropped into a window in the visual GUI builder)

Now we need a bit more managed C++ wizardry to fill up the wrapper, here it is:

OpenCVImageWrapper^ getFromOpenCV() {
Mat im = imread("someimage.jpg");

OpenCVImageWrapper^ i = gcnew OpenCVImageWrapper();
i->buf = gcnew cli::array<byte>(im.rows * im.step);
System::Runtime::InteropServices::Marshal::Copy(System::IntPtr::IntPtr(,i->buf,0,im.rows * im.step);

i->width = im.cols;
i->height = im.rows;
i->row_stride = im.step;
i->channels = im.channels();
i->buf_size = im.rows * im.step;

return i;

We're pretty much done. Basic stuff!

It's not memory optimized as I'm copying the buffer, but it gets the job done.