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: 2832
Joined: Sun Jan 03, 2010 5:45 pm

Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB » Wed Oct 07, 2020 6:09 pm

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
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 224
Joined: Fri Dec 12, 2008 10:31 am

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by ollydbg23 » Thu Dec 10, 2020 5:02 am

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: 2832
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB » Thu Dec 10, 2020 6:19 am

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
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 224
Joined: Fri Dec 12, 2008 10:31 am

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by ollydbg23 » Tue Dec 22, 2020 2:48 am

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: 2832
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB » 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.
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
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 224
Joined: Fri Dec 12, 2008 10:31 am

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by ollydbg23 » Wed Dec 23, 2020 7:19 am

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: 2832
Joined: Sun Jan 03, 2010 5:45 pm

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Post by PB » Wed Dec 23, 2020 8:17 am

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.

Post Reply