Page 1 of 1

Converting OpenCV bitmap (Mat) to wxBitmap

Posted: Wed Oct 07, 2020 6:09 pm
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

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Posted: Thu Dec 10, 2020 5:02 am
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.

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Posted: Thu Dec 10, 2020 6:19 am
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.

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Posted: Tue Dec 22, 2020 2:48 am
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?

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Posted: Tue Dec 22, 2020 4:25 pm
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).

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Posted: Wed Dec 23, 2020 7:19 am
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.

Re: Converting OpenCV bitmap (Mat) to wxBitmap

Posted: Wed Dec 23, 2020 8:17 am
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.