Converting OpenCV bitmap (Mat) to wxBitmap

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Post Reply
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB »

OpenCV itself can show a bitmap using imshow() function but sometimes one may want to display a bitmap acquired with OpenCV using a wxWidgets GUI. The most convenient class for doing that in wxWidgets is wxBitmap.

The function

Code: Select all

bool ConvertMatBitmapTowxBitmap(const cv::Mat& matBitmap, wxBitmap& bitmap)
converts an OpenCV bitmap encoded as BGR CV_8UC3 (the most common format) to a wxBitmap. The function also comes with a simple program which uses OpenCV and wxWidgets to acquire and display bitmaps coming from several sources: image file, video file, default webcam, and IP camera. The program also benchmarks how long a bitmap took to acquire, convert, and display.

All the code and additional information is available here:
https://github.com/PBfordev/wxopencvtest

UI of the test app
wxopencvtest.png
ollydbg23
Super wx Problem Solver
Super wx Problem Solver
Posts: 438
Joined: Fri Dec 12, 2008 10:31 am

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by ollydbg23 »

Hi, your tutorial is good!

I have a question:

I have used the cvMat <----> wxImage functions for a very long time, such as in this post:

Cool-Emerald: OpenCV with wxWidgets
Also, How to obtain Alpha from cv::mat (For wxWidgets::wxImage) - OpenCV Q&A Forum or image processing - OpenCV with other GUI (like Qt or WxWidgets) on Win32 VC++ - Stack Overflow

What is the advantage if you directly translate the cvmat to wxBitmap?

Thanks.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB »

ollydbg23 wrote: Thu Dec 10, 2020 5:02 am What is the advantage if you directly translate the cvmat to wxBitmap?
If you want to display an OpenCV image with wxWidgets, you need a wxBitmap, not a wxImage. If you just want to save an image, you can use OpenCV functions, without converting the image to wxImage.

Please notice that my code does not support alpha, as it is often not needed, particularly when processing video.
ollydbg23
Super wx Problem Solver
Super wx Problem Solver
Posts: 438
Joined: Fri Dec 12, 2008 10:31 am

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by ollydbg23 »

You are right, and you code runs faster than my old code:

My old code looks like below, the variable img is the OpenCV's cv::Mat.

Code: Select all

    wxStopWatch stopWatch;
    long        time = 0;
    stopWatch.Start();

    cv::Size sz = img.size();
    int imageWidth = sz.width;
    int imageHeight = sz.height;
    cv::cvtColor(img, img, cv::COLOR_RGB2BGR);
    wxImage Image( imageWidth, imageHeight, img.data, TRUE );

    wxBitmap bp= wxBitmap(Image, -1); // ...to get the corresponding bitmap

    time = stopWatch.Time();
    wxLogMessage("Convert Time=%d", time);
By the way, I have to add a linker option

Code: Select all

-lgdi32
, because you use the Win32 API function: SetDIBits in your library. Otherwise, you will get a linker error.

I did see that in the wxBitmap's document, this library also support Alpha channel, so I'm not sure it is possible to enable this feature in your code?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB »

ollydbg23 wrote: Tue Dec 22, 2020 2:48 am You are right, and you code runs faster than my old code:
[/code]
TBH, I do not understand how the old code works. I know little about OpenCV but I would say this

Code: Select all

cv::cvtColor(img, img, cv::COLOR_RGB2BGR);
converts the mat from RGB to BGR colorspace. However, wxImage expects RGB (and OpenCV bitmaps are in BGR by default)?

Anyway, he old code was not very efficient if you wanted to convert cv::Mat to wxBitmap as it did:
1. Convert the mat bitmap from one colorspace to another.
2. Created a wxImage (this should be very fast).
3. Converted a wxImage to wxBitmap.
ollydbg23 wrote: Tue Dec 22, 2020 2:48 am By the way, I have to add a linker option

Code: Select all

-lgdi32
, because you use the Win32 API function: SetDIBits in your library. Otherwise, you will get a linker error.
This is odd, CMake should have added this library automatically when linking with wxCore. It did for me both with GCC and MSVC.
ollydbg23 wrote: Tue Dec 22, 2020 2:48 am I did see that in the wxBitmap's document, this library also support Alpha channel, so I'm not sure it is possible to enable this feature in your code?
wxBitmap can have an alpha channel (and a mask as well) but as I wrote before, I believe images with alpha are rarely coming from OpenCV.

The code could be adapted but I am not going to do that, as I do not need it and I am not sure how much faster it would be instead of just using wxAlphaPixelData when converting cv::Mat to wxBitmap (or wxImagePixelData when converting to wxImage).
ollydbg23
Super wx Problem Solver
Super wx Problem Solver
Posts: 438
Joined: Fri Dec 12, 2008 10:31 am

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by ollydbg23 »

Thanks for the reply.
PB wrote: Tue Dec 22, 2020 4:25 pm
ollydbg23 wrote: Tue Dec 22, 2020 2:48 am You are right, and you code runs faster than my old code:
[/code]
TBH, I do not understand how the old code works. I know little about OpenCV but I would say this

Code: Select all

cv::cvtColor(img, img, cv::COLOR_RGB2BGR);
converts the mat from RGB to BGR colorspace. However, wxImage expects RGB (and OpenCV bitmaps are in BGR by default)?

Anyway, he old code was not very efficient if you wanted to convert cv::Mat to wxBitmap as it did:
1. Convert the mat bitmap from one colorspace to another.
2. Created a wxImage (this should be very fast).
3. Converted a wxImage to wxBitmap.
You are right, the OpenCV cv::Mat default is the BGR. So, my code should be :cv::COLOR_BGR2RGB, because wxImage is RGB.



ollydbg23 wrote: Tue Dec 22, 2020 2:48 am By the way, I have to add a linker option

Code: Select all

-lgdi32
, because you use the Win32 API function: SetDIBits in your library. Otherwise, you will get a linker error.
This is odd, CMake should have added this library automatically when linking with wxCore. It did for me both with GCC and MSVC.
I'm directly adding your h/cpp file to my Codeblocks cbp file, so I have to add this linker option manually.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB »

ollydbg23 wrote: Wed Dec 23, 2020 7:19 am I'm directly adding your h/cpp file to my Codeblocks cbp file, so I have to add this linker option manually.
I still do not understand how could your program link to wxCore but not to GDI32 and still build. But who knows...

Anyway, the source code is provided just as a header and source, these cannot (except using MSVC only pragma) nor should not add a library to link with, that is the responsibility of a user.
polapola8
In need of some credit
In need of some credit
Posts: 1
Joined: Tue Mar 29, 2022 11:41 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by polapola8 »

Hi, i'm a beginner in c++. I want to integrate the gui of wx with a strem in opencv. I'd like to know if your readme on github is updated in order to try it on my project. Thanks!
zura
Earned some good credits
Earned some good credits
Posts: 104
Joined: Thu Apr 02, 2009 8:11 pm
Location: Tbilisi, Georgia

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by zura »

Thanks for your effort!

Feedback: besides 3 channel/24 bits, another popular format is greyscale/single channel. Would be nice to have the support of it as well.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB »

zura wrote: Thu Jun 09, 2022 8:35 pm besides 3 channel/24 bits, another popular format is greyscale/single channel. Would be nice to have the support of it as well.
TBH, converting from CV::Mat to wxBitmap is trivial. The only purpose I wrote an extra function like that was to use when possible the fast native function exploiting that CV_8UC3 is stored the same way in cv::Mat as in a Windows DIB.
zura
Earned some good credits
Earned some good credits
Posts: 104
Joined: Thu Apr 02, 2009 8:11 pm
Location: Tbilisi, Georgia

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by zura »

I'm trying with cvtColor (with COLOR_BGR2RGB flag when the image has 3 channels) which is utilizing a parallelism under the hood, but it messes up the colors.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB »

zura wrote: Fri Jun 10, 2022 10:02 pm I'm trying with cvtColor (with COLOR_BGR2RGB flag when the image has 3 channels) which is utilizing a parallelism under the hood, but it messes up the colors.
But this is entirely within OpenCV, right? I have no experience with the OpenCV parallel framework.
Post Reply