Thursday, November 23, 2017

OpenCV with wxWidgets

  1. Introduction
  2. Linux
  3. Windows
  4. References

Introduction

In this article, using OpenCV with wxWidgets is discussed with examples. For that, OpenCV and wxWidgets need to be installed in your system. Installing and using them on Linux and Windows platforms can be found at the following links.

Linux

Building an application using OpenCV and wxWidgets in Linux terminal is simple. As an example, a simple program called wxcvsimple.cpp (online) is discussed below. At the start of the program, in OnInit() method of the Application,
wxInitAllImageHandlers();
is called. Then, wxStaticBitmap variables are declared in MyFrame class, a derived class of wxFrame, to display images. The following code can be used to initialize wxStaticBitmap in the constructor of MyFrame class.

lena = new wxStaticBitmap(this,wxID_ANY,wxBitmap(wxT("lena.jpg"),
 wxBITMAP_TYPE_JPEG),wxPoint(0,0),wxSize(256, 256));


To convert an image between OpenCV::Mat and wxWidgets::wxImage, the functions - mat_from_wx and wx_from_mat are used which are shown in the following list, util.h (online) [Dad10; pkl15].
//File: util.h
//Description: Functions to convert wxImage and OpenCV Mat
//Author: Yan Naing Aye
//MIT License - Copyright (c) 2017 Yan Naing Aye
#include < wx/wx.h >
#include < opencv2/opencv.hpp >
using namespace cv;
wxImage wx_from_mat(Mat &img) {
    Mat im2;
    if(img.channels()==1){cvtColor(img,im2,CV_GRAY2RGB);}
 else if (img.channels() == 4) { cvtColor(img, im2, CV_BGRA2RGB);}
    else {cvtColor(img,im2,CV_BGR2RGB);}
 long imsize = im2.rows*im2.cols*im2.channels();
    wxImage wx(im2.cols, im2.rows,(unsigned char*)malloc(imsize), false);
 unsigned char* s=im2.data;
 unsigned char* d=wx.GetData();
 for (long i = 0; i < imsize; i++) { d[i] = s[i];}
    return wx;
}
Mat mat_from_wx(wxImage &wx) {
    Mat im2(Size(wx.GetWidth(),wx.GetHeight()),CV_8UC3,wx.GetData());
    cvtColor(im2,im2,CV_RGB2BGR);
    return im2;
}
Listing. util.h

In the constructor, imread in OpenCV is used to load thiri.jpg. The resulting Mat is converted into wxImage using wx_from_mat. It is then displayed on the GUI frame using SetBitmap method of wxStaticBitmap.

Thereafter, a wxImage variable is declared and load lena.jpg using LoadFile method of wxWidget. The resulting wxImage is converted into OpenCV::Mat using mat_from_wx function. Then, the image is displayed using imshow of OpenCV. The program wxcvsimple.cpp (online) is shown in the following list.
//File: wxcvsimple.cpp
//Description: A simple example to use OpenCV with wxWidgets
//Author: Yan Naing Aye
//Date: 2017 November 01
//MIT License - Copyright (c) 2017 Yan Naing Aye

#include < wx/wx.h >
#include < opencv2/opencv.hpp >
#include "util.h"
using namespace cv;

class MyFrame : public wxFrame
{
    wxStaticBitmap *lena;
    wxStaticBitmap *thiri;
public:
    MyFrame(const wxString& title);

};
MyFrame::MyFrame(const wxString& title)
  : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(512, 256))
{
    Centre();
    lena = new wxStaticBitmap(this,wxID_ANY,wxBitmap(wxT("lena.jpg"),
  wxBITMAP_TYPE_JPEG),wxPoint(0,0),wxSize(256, 256));
    thiri = new wxStaticBitmap(this,wxID_ANY,wxBitmap(wxT("lena.jpg"),
  wxBITMAP_TYPE_JPEG),wxPoint(256,0),wxSize(256, 256));

    //From opencv to wx
    Mat imcv1=imread("thiri.jpg",CV_LOAD_IMAGE_COLOR);
    wxBitmap imwx1=wx_from_mat(imcv1);
    thiri->SetBitmap(imwx1);

    //From wx to opencv
    wxImage imwx2;
    imwx2.LoadFile(wxT("lena.jpg"), wxBITMAP_TYPE_JPEG);
    Mat imcv2=mat_from_wx(imwx2);
    namedWindow("Img",CV_WINDOW_AUTOSIZE);
    imshow("Img",imcv2);
}

class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};

IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
    if ( !wxApp::OnInit() )
        return false;
    wxInitAllImageHandlers();
    MyFrame *frame = new MyFrame(wxT("Simple wxWidgets + OpenCV"));
    frame->Show(true);

    return true;
}
Listing. wxcvsimple.cpp

The following command can be used to build the program.
g++ wxcvsimple.cpp util.h `wx-config --cxxflags --libs std`
        `pkg-config --cflags --libs opencv` -o wxcvsimple
The output of running it using ./wxcvsimple command is shown below.

Figure. A simple example using OpenCV with wxWidgets.


Code::Blocks

To use OpenCV with wxWidgets in Code::Blocks, a new empty project is created as shown in the following figure. Give it a name such as wxcv (online). Choose GNU GCC Compiler.

Figure. Creating an empty project in Code::Blocks.


Click File Menu → New → Empty File, and create a source file, wxcv.cpp as shown in the following list.
#include < wx/wx.h >
#include < opencv2/opencv.hpp >
using namespace cv;

class Simple : public wxFrame
{
public:
    Simple(const wxString& title);

};
Simple::Simple(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150))
{
  Centre();
  Mat img=imread("grove.jpg",CV_LOAD_IMAGE_COLOR);
  namedWindow("Img",CV_WINDOW_AUTOSIZE);
  imshow("Img",img);
}

class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};

IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
    Simple *simple = new Simple(wxT("Simple"));
    simple->Show(true);

    return true;
}
Listing. wxcv.cpp

Click Project Menu → Build Options... and fill the following line in Compiler settings tab → Other compiler options for both Debug and Release.
`wx-config --cxxflags` `pkg-config --cflags opencv` 

Figure. Compiler options


Similarly, add the following line in Linker settings tab → Other linker options.
`wx-config --libs std` `pkg-config  --libs opencv`

Figure. Linker options


When the program is built and run by pressing F9, the output can be seen as follow.

Figure. Running an example for OpenCV with wxWidgets in Code::Blocks.
As optional steps, if you want IDE to know more about the project, you can click Project Menu → Build Options... and add /usr/local/include and /usr/local/include/wx-3.0 in Search directories tab → Compiler tab for both Debug and Release configurations. Similarly, in the Linker tab beside, you can add /usr/local/lib.

Windows

Visual Studio

To run OpenCV with wxWidgets on Windows, duplicate C:/wxWidgets303/samples/minimal folder as minimalcv (See [Eme17]. Open minimal_vc9.vcproj and copy OpenCV320.props into the project folder which can be found at the following link.

https://github.com/yan9a/OpenCV_Projects/blob/master/img_wins_vs2015_x64/img_wins/OpenCV320.props

Click View menu → Other Windows → Property Manager, and right click on minimal in Property window. Then choose Add existing property sheet and, add OpenCV320.props as shown in the following figure.

Figure. Adding the Property Sheet for OpenCV.


Choose x64 in the drop down list for Solution Platforms. Right click on Source Files in Solution Explorer, choose Add Existing Item ... and add util.h (online). Then, modify minimal.cpp (online) as shown in the following list. When the program is built and run, the output of the program can be seen as shown in the following figure.
//File: minimalcv.cpp
//Description: A simple example to use OpenCV with wxWidgets
//Author: Yan Naing Aye
//Date: 2017 November 07
//MIT License - Copyright (c) 2017 Yan Naing Aye

#include < wx/wx.h >
#include < opencv2/opencv.hpp >
#include "util.h"
#include < string >
using namespace std;
using namespace cv;

class MyFrame : public wxFrame
{
 wxStaticBitmap *thiri;
public:
 MyFrame(const wxString& title);

};
MyFrame::MyFrame(const wxString& title)
 : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(512, 600))
{
 Centre();
 thiri = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxT("C:/opencv/thiri.png"), 
                    wxBITMAP_TYPE_PNG), wxPoint(256, 0), wxSize(512,512));

 //From opencv to wx
 Mat imcv1 = imread("C:/opencv/thiri.png",IMREAD_UNCHANGED);
 string str = "Channels:" + to_string(imcv1.channels());
 putText(imcv1, str, Point(100, 100), FONT_HERSHEY_PLAIN, 4.0, CV_RGB(128, 0, 128), 4.0);
 wxBitmap imwx1 = wx_from_mat(imcv1);
 thiri->SetBitmap(imwx1);
}

class MyApp : public wxApp
{
public:
 virtual bool OnInit();
};

IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
 if (!wxApp::OnInit())
  return false;
 wxInitAllImageHandlers();
 MyFrame *frame = new MyFrame(wxT("Simple wxWidgets and OpenCV"));
 frame->Show(true);

 return true;
}
Listing. minimal.cpp


Figure. Using OpenCV with wxWidgets in Visual Studio on Windows.




Related Posts



References

[Dad10] Jive Dadson. OpenCV Image and wxImage Conversion. 2010.
url: https://stackoverflow.com/a/2241517.

[pkl15] pklab. Alpha from cv::mat for wxWidgets::wxImage. 2015.
url: http://answers.opencv.org/question/76540/how-to-obtain-alpha-from-cvmat-for-wxwidgetswximage/.

[Eme17] Cool Emerald. Cross-platform C++ programming with wxWidgets. 2017.
url: http://coolemerald.blogspot.sg/2017/10/cross-platform-c-programming-with.html#wxvs.

No comments:

Post a Comment

Comments are moderated and don't be surprised if your comment does not appear promptly.