Convert Opencv Mat to C# Bitmap

Conversion from Opencv Mat to C# bitmap isn't a difficult task. But this conversion needs to be done from the primitive level of both Opencv Mat and C# Bitmap. Simply all the images are created from set of bytes, therefore it is necessary to create System.Drawing.Bitmat from bytes of cv::Mat. Also you will need to do this conversion in a CLI project. Total instructions can be found in following 2 articles.
  1. Call Opencv functions from C#
  2. Call Opencv functions from C# with bitmap



This article describes how to convert C# Bitmap to Opencv Mat.
Convert C# Bitmap to Opencv Mat

If you already know how to create and configure CLI project in visual studio, simply use following function in CLI project to convert Opencv Mat to C# Bitmap.

System::Drawing::Bitmap^ MatToBitmap(Mat srcImg){
    int stride = srcImg.size().width * srcImg.channels();//calc the srtide
    int hDataCount = srcImg.size().height;
   
    System::Drawing::Bitmap^ retImg;
       
    System::IntPtr ptr(srcImg.data);
   
    //create a pointer with Stride
    if (stride % 4 != 0){//is not stride a multiple of 4?
        //make it a multiple of 4 by fiiling an offset to the end of each row


       
//to hold processed data
        uchar *dataPro = new uchar[((srcImg.size().width * srcImg.channels() + 3) & -4) * hDataCount];

        uchar *data = srcImg.ptr();

        //current position on the data array
        int curPosition = 0;
        //current offset
        int curOffset = 0;

        int offsetCounter = 0;

        //itterate through all the bytes on the structure
        for (int r = 0; r < hDataCount; r++){
            //fill the data
            for (int c = 0; c < stride; c++){
                curPosition = (r * stride) + c;

                dataPro[curPosition + curOffset] = data[curPosition];
            }

            //reset offset counter
            offsetCounter = stride;

            //fill the offset
            do{
                curOffset += 1;
                dataPro[curPosition + curOffset] = 0;

                offsetCounter += 1;
            } while (offsetCounter % 4 != 0);
        }

        ptr = (System::IntPtr)dataPro;//set the data pointer to new/modified data array

        //calc the stride to nearest number which is a multiply of 4
        stride = (srcImg.size().width * srcImg.channels() + 3) & -4;

        retImg = gcnew System::Drawing::Bitmap(srcImg.size().width, srcImg.size().height,
            stride,
            System::Drawing::Imaging::PixelFormat::Format24bppRgb,
            ptr);
    }
    else{

        //no need to add a padding or recalculate the stride
        retImg = gcnew System::Drawing::Bitmap(srcImg.size().width, srcImg.size().height,
            stride,
            System::Drawing::Imaging::PixelFormat::Format24bppRgb,
            ptr);
    }
   
    array^ imageData;
    System::Drawing::Bitmap^ output;

    // Create the byte array.
    {
        System::IO::MemoryStream^ ms = gcnew System::IO::MemoryStream();
        retImg->Save(ms, System::Drawing::Imaging::ImageFormat::Png);
        imageData = ms->ToArray();
        delete ms;
    }

    // Convert back to bitmap
    {
        System::IO::MemoryStream^ ms = gcnew System::IO::MemoryStream(imageData);
        output = (System::Drawing::Bitmap^)System::Drawing::Bitmap::FromStream(ms);
    }

    return output;
}

Continue Reading...

Convert C# Bitmap to Opencv Mat

Conversion from C# bitmap to Opencv Mat isn't a difficult task. But this conversion needs to be done from the primitive level of both Opencv Mat and C# Bitmap. Simply all the images are created from set of bytes, therefore it is necessary to create cv::Mat from bytes of System.Drawing.Bitmat. Also you will need to do this conversion in a CLI project. Total instructions can be found in following 2 articles.
  1. Call Opencv functions from C#
  2. Call Opencv functions from C# with bitmap

This article describes how to convert Opencv Mat to C# Bitmap.
Convert Opencv Mat to C# Bitmap

If you already know how to create and configure CLI project in visual studio, simply use following function in CLI project to convert C# Bitmap to Opencv Mat.

Mat BitmapToMat(System::Drawing::Bitmap^ bitmap)
{
    IplImage* tmp;

    System::Drawing::Imaging::BitmapData^ bmData = bitmap->LockBits(System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height), System::Drawing::Imaging::ImageLockMode::ReadWrite, bitmap->PixelFormat);
    if (bitmap->PixelFormat == System::Drawing::Imaging::PixelFormat::Format8bppIndexed)
    {
        tmp = cvCreateImage(cvSize(bitmap->Width, bitmap->Height), IPL_DEPTH_8U, 1);
        tmp->imageData = (char*)bmData->Scan0.ToPointer();
    }

    else if (bitmap->PixelFormat == System::Drawing::Imaging::PixelFormat::Format24bppRgb)
    {
        tmp = cvCreateImage(cvSize(bitmap->Width, bitmap->Height), IPL_DEPTH_8U, 3);
        tmp->imageData = (char*)bmData->Scan0.ToPointer();
    }

    bitmap->UnlockBits(bmData);

    return Mat(tmp);
}
Continue Reading...

Call OpenCV functions from C#.net (Bitmap to Mat and Mat to Bitmap)


This is the second article of the article series which provide answers to following question! How to call OpenCV functions from C#.net or VB.net. Specially this article describes, how to pass System.Drawing.Bitmap to OpenCV and get a resultant image as System.Drawing.Bitmap from OpenCV.


Note that System.Drawing.Bitmap is the class type which allow you to manipulate images in C# while OpenCV treat images as cv::Mat (matrix). Therefore we need a way to convert from Bitmap to Mat vice versa in order to process and show processed images. This is the place where wrapper involved. For more details about wrappers, please refer previous article. 


From Previous Article...
So now we are going to create this wrapper for our application. Since we are dealing with .net framework, we can use CLR (Common Language Runtime) technique to create this wrapper. First you have to create a CLR project in Visual Studio. This post will describe, how to call Opencv functions from winfrom/C# and apply an Opencv filter to an image and show the Opencv window from winform.


Download complete Visual Studio project.

Step 1 - Create CLI Project

First of all we need to have a CLI project where we can call C++ functions from .net. You can follow the steps from previous article to create a CLI project.

Step 2 - Create converter function from Bitmap to Mat

Now we need to convert System.Drawing.Bitmap to cv::Mat. To do this conversion, we need to get to the primitive level of both data type. That's mean, we can simply think every image has created from a set of bytes. So bytes can live in both C++ and C#. Therefore the cv::Mat should be created from the set of bytes of Bitmap. Simply copy all bytes from Bitmap to Mat, finally it will create Mat from Bitmap. Use following function to do this conversion.

Mat BitmapToMat(System::Drawing::Bitmap^ bitmap)
{
    IplImage* tmp;

    System::Drawing::Imaging::BitmapData^ bmData = bitmap->LockBits(System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height), System::Drawing::Imaging::ImageLockMode::ReadWrite, bitmap->PixelFormat);
    if (bitmap->PixelFormat == System::Drawing::Imaging::PixelFormat::Format8bppIndexed)
    {
        tmp = cvCreateImage(cvSize(bitmap->Width, bitmap->Height), IPL_DEPTH_8U, 1);
        tmp->imageData = (char*)bmData->Scan0.ToPointer();
    }

    else if (bitmap->PixelFormat == System::Drawing::Imaging::PixelFormat::Format24bppRgb)
    {
        tmp = cvCreateImage(cvSize(bitmap->Width, bitmap->Height), IPL_DEPTH_8U, 3);
        tmp->imageData = (char*)bmData->Scan0.ToPointer();
    }

    bitmap->UnlockBits(bmData);

    return Mat(tmp);
}

Step 3 - Add System.Drawing namespace reference.

Once you add above function to your CLI project, you will get an error on System::Drawing::Bitmap. The reason for this error is that the project has no reference to System::Drawing::Bitmap. Follow below steps to add the reference.

Open project properties of CLI project.
















Select Common Properties then References , Click on Add New References... It will open a window that can select dll files where you can add as references.















Select Framework under Assembly category. Then mark System.Drawing.









Now the project has referenced System.Drawing, and you should not see any compile errors in the function.

Step 4 - Create converter function from Mat to Bitmap

Same as previous conversion, we need to perform this conversion from the primitive level. That's mean we need to reconstruct the Bitmap from Mat's image data bytes. Use following function to convert from cv::Mat to System.Drawing.Bitmap.

System::Drawing::Bitmap^ MatToBitmap(Mat srcImg){
    int stride = srcImg.size().width * srcImg.channels();//calc the srtide
    int hDataCount = srcImg.size().height;
   
    System::Drawing::Bitmap^ retImg;
       
    System::IntPtr ptr(srcImg.data);
   
    //create a pointer with Stride
    if (stride % 4 != 0){//is not stride a multiple of 4?
        //make it a multiple of 4 by fiiling an offset to the end of each row


       
//to hold processed data
        uchar *dataPro = new uchar[((srcImg.size().width * srcImg.channels() + 3) & -4) * hDataCount];

        uchar *data = srcImg.ptr();

        //current position on the data array
        int curPosition = 0;
        //current offset
        int curOffset = 0;

        int offsetCounter = 0;

        //itterate through all the bytes on the structure
        for (int r = 0; r < hDataCount; r++){
            //fill the data
            for (int c = 0; c < stride; c++){
                curPosition = (r * stride) + c;

                dataPro[curPosition + curOffset] = data[curPosition];
            }

            //reset offset counter
            offsetCounter = stride;

            //fill the offset
            do{
                curOffset += 1;
                dataPro[curPosition + curOffset] = 0;

                offsetCounter += 1;
            } while (offsetCounter % 4 != 0);
        }

        ptr = (System::IntPtr)dataPro;//set the data pointer to new/modified data array

        //calc the stride to nearest number which is a multiply of 4
        stride = (srcImg.size().width * srcImg.channels() + 3) & -4;

        retImg = gcnew System::Drawing::Bitmap(srcImg.size().width, srcImg.size().height,
            stride,
            System::Drawing::Imaging::PixelFormat::Format24bppRgb,
            ptr);
    }
    else{

        //no need to add a padding or recalculate the stride
        retImg = gcnew System::Drawing::Bitmap(srcImg.size().width, srcImg.size().height,
            stride,
            System::Drawing::Imaging::PixelFormat::Format24bppRgb,
            ptr);
    }
   
    array^ imageData;
    System::Drawing::Bitmap^ output;

    // Create the byte array.
    {
        System::IO::MemoryStream^ ms = gcnew System::IO::MemoryStream();
        retImg->Save(ms, System::Drawing::Imaging::ImageFormat::Png);
        imageData = ms->ToArray();
        delete ms;
    }

    // Convert back to bitmap
    {
        System::IO::MemoryStream^ ms = gcnew System::IO::MemoryStream(imageData);
        output = (System::Drawing::Bitmap^)System::Drawing::Bitmap::FromStream(ms);
    }

    return output;
}



Now we can convert cv::Mat to System.Drawing.Bitmap. You can call BitmapToMat() function to convert C# Bitmap and use converted Mat to do image processing from OpenCV, so OpenCV will produce processed image as Mat type, here you can use MatToBitmap() function to return Bitmap type object back to C#. Now you can treat this processed Bitmap as a normal Bitmap in C#.

Step 5 - Use converter functions and do image processing.

You can use above 2 functions and your own image processing code to create processed image from an input image. Here, I am trying to apply "medianBlur" opencv filter to C# Bitmap image. This is a sample code which show how to use these conversion functions along some opencv functions.


System::Drawing::Bitmap^ MyOpenCvWrapper::ApplyFilter(System::Drawing::Bitmap^ bitmap){
    Mat image = BitmapToMat(bitmap);//convert Bitmap to Mat
    if (!image.data){
        return nullptr;
    }

    Mat dstImage;//destination image

    //apply the Filter
    medianBlur(image, dstImage, 25);

    //convert Mat to Bitmap
    System::Drawing::Bitmap^ output = MatToBitmap(dstImage);

    return output;
}

Step 6 - Call from C#

Now you can call this function from C# by passing a Bitmap type object to the method and it will return the filter applied image back as a Bitmap. So you can use this returned Bitmap as a normal Bitmap in C#.

//open jpg file as Bitmap
Bitmap img = (Bitmap)Bitmap.FromFile(@"C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg");

OpenCvDotNet.MyOpenCvWrapper obj = new OpenCvDotNet.MyOpenCvWrapper();
Bitmap output = obj.ApplyFilter(img);//call opencv functions and get filterred image

 output.Save("test.jpg");//save processed image

If you put this code in an event handler in C#, it will looks like this,

Step 7 - Use returned Bitmap from OpenCV in C#

you can use this returned Bitmap as a normal Bitmap in C# such as setting the image for PictureBox. Following code will open a Bitmap from a file, process in opencv to apply filter and show the results in a C# PictureBox control.

private void btnOpen_Click(object sender, EventArgs e)
{
    //allow user to open jpg file
    OpenFileDialog dlogOpen = new OpenFileDialog();
    dlogOpen.Filter = "Jpg Files|*.jpg";
    if (dlogOpen.ShowDialog() != System.Windows.Forms.DialogResult.OK)
        return;

    //open jpg file as Bitmap
    Bitmap img = (Bitmap)Bitmap.FromFile(dlogOpen.FileName);

    pbSrcImg.Image = img;//set picture box image to UI

    OpenCvDotNet.MyOpenCvWrapper processor = new OpenCvDotNet.MyOpenCvWrapper();
    Bitmap processedImg = processor.ApplyFilter(img);//call opencv functions and get filterred image

    pbDstImage.Image = processedImg;//set processed image to picture box
}

Where pbSrcImg and pbDstImage are PictureBox UI controls in C#. Once you open a jpg image it will show the UI as follow,



Download complete Visual Studio project.


From Previous Article...
So now we are going to create this wrapper for our application. Since we are dealing with .net framework, we can use CLR (Common Language Runtime) technique to create this wrapper. First you have to create a CLR project in Visual Studio. This post will describe, how to call Opencv functions from winfrom/C# and apply an Opencv filter to an image and show the Opencv window from winform.

Continue Reading...

Call OpenCV functions from C#.net

OpenCV is a C++ library, .net is different platform. Therefore, how to call Opencv functions from .net or how to call Opencv functions from C# or vb.net. This is possible because remember we are using Visual C++ for our Opencv projects and VC++ also a part of .net platform. This will allow you to wrap our specific opencv functions to be able to call from C#. A wrapper means an intermediate party which act as a communicator between 2 different sides. Simply you can use this technique to keep your front end GUI in C#, vb.net or WPF while keeping opencv as the back end to do image processing.

So now we are going to create this wrapper for our application. Since we are dealing with .net framework, we can use CLR (Common Language Runtime) technique to create this wrapper. First you have to create a CLR project in Visual Studio.

This post will describe, how to call Opencv functions from winfrom/C# and apply an Opencv filter to an image and show the Opencv window from winform.

Step 1 – Create a CLR project

Click on File-->New Project and select CLR under Visual C++ then select Class Library.

Then you will get a sample header file and cpp file for your wrapper class where you have to put all the functions' headers in class definition (in .h file) to be able to call from C#.

Step 2 -Apply OpenCV Configurations to the project.

 You can set all the project properties for Building and Linking a normal Opencv C++ project or you can import all the properties at once from an existing Property sheet as explained in this article.

Step 3 - Create CLR functions to call from C#


Now create a method in CLR class to call from C#. Here we need to keep something in mind, that is, C# deal with pointers (unless you specify as not a pointer/reference). Therefor all the parameters for this method should be pass as a pointer. But for now we will create a method without parameters.

Type following code in your class
    public:
        void ApplyFilter();


Now ApplyFilter is the method that we are going to call from C# using an object created from MyOpenCvWrapper class.

Step 4 - Include Opencv headers

Add all the header files of opencv that you need for this class, Here we just need cv.h and highgui.h. Remember to add include derivatives to your header file

#include <opencv\cv.h>
#include <opencv\highgui.h>


Step 5 - Code for the method

Open your cpp file and enter following code. This is the function that we are going to call from opencv and this is the code to do image processing. you can follow normal way to implement a class in C++.
#include "OpenCvDotNet.h"

using namespace OpenCvDotNet;
using namespace cv;

void MyOpenCvWrapper::ApplyFilter(){
    Mat image = imread("C:\\Pictures\\Hydrangeas.jpg");
    Mat dstImage;

    if (!image.data){
        return;
    }

    //Apply the Filter
    GaussianBlur(image, dstImage, Size(31, 31), 0);

    namedWindow("Image Window", CV_WINDOW_KEEPRATIO);
    imshow("Image Window", dstImage);
}



Code Explanation -
This code will open the image named "Hydrangeas.jpg" from "C:\Pictures" directory and check whether image opened successfully or not. Then it will apply a filter and show the result in an opencv window.

Step 6 - Add reference to C# project

Create and add a new project to your solution by Right click on your solution.

Now you can create either "Windows Form Application" or "WPF Application" or any other project type to use your opencv code. For this article I am using "Windows Form Application". After adding Winform project to your solution, your solution explorer should has 2 projects (CLR project and winform project).


Now you can Right click on Reference on WinFormProject and add reference to CLI project. You can find your project under Solutions/Project.

Step 6 - Call OpenCV from Winform project

Now you have made the link between winform and cli project which includes opencv calls. Note that the architecture (32bit or 64bit) of both projects should be same and the .net framework versions should be same on both projects to build your whole solution.

Use the class that we created from CLI project to create an object in C# and call the method that we created in CLI project from C#. then you should see the success !

I just added a button to my winform and call the method from there.

private void button1_Click(object sender, EventArgs e)
{
   OpenCvDotNet.MyOpenCvWrapper obj = new OpenCvDotNet.MyOpenCvWrapper();
   obj.ApplyFilter();
}

Step 7 - Run and test

Now you can run your winform application. Remember to set the winform project as the "Startup Project"
Then once you clicked on the button, you should see an opencv window showing a blur image.



This is a very simple way to call and get an output from opencv using winform/C#. My next post will describe how to pass a C# System.Drawing.Bitmap to CLI project and get the output image as a System.Drawing.Bitmap from the Opencv CLI.
Continue Reading...

Create OpenCV property sheets in Visual Studio to store properties



OpenCV is a very famous open source image processing library. Most of the Windows users are using OpenCV on Visual Studio IDE which provides C/C++ coding. Anyway You have to set some properties in each and every Visual Studio project, if you need to use OpenCV. This is very hard to me :). Because we have to set number of properties each and every times when you are creating a new project.

The solution for this is "Create a property sheet which can hold all the OpenCV properties". Following steps will describes How to create an OpenCV property sheet in Visual Studio 2013.


Step 1 - Create a new C++ project

You can follow normal steps to create a new C++ project. File --> New --> Project

Step 2 - Create new property sheet

First you have to open "Property Manager" window to manage all the property sheets for this project. Click on View --> Other Window --> Property Manager.

Then you will see a window similar to following window.
Here we have to create 2 property sheets for Debug and Release. Also If your project is 64 bit then you will have another 2 items as "Debug | x64" and "Release | x64", then you have to create two 64 bit property sheets separately. Anyway this article will guide you to create 32 bit property sheets.

Now Right click on "Debug | Win32" and select "Add New Project Property Sheet..." and give a name for your property sheet (Here I am using OpenCVDebug as the name).
Then you will see your new property sheet on Property Manager.

Step 3 - Set OpenCV properties (Debug)

Now we are going to set all the opencv properties for Debug mode. Right click on your new Property sheet and select Properties. There are 3 things that you have to set in here.
  1. OpenCV include directory
  2. OpenCV library directory
  3. OpenCV libraries

1. Setting OpenCV include directories

Go to General tab under C/C++ and click on Edit  under Additional Include Directories. Now set the directory path of your opencv include directory. (You can find this directory under build folder in opencv folder)

2. Setting OpenCV library directory

Go to General tab under Linker and add a new directory path for the Additional Library Directories as the library directory which includes 32bit lib files for your compiler version. Here I am using Visual Studio 2013 therefore I have to select vc12 and x86 since I am crating 32bit application.

3. Setting OpenCV libraries

Go to Input tab under Linker to set libraries for the opencv. Click Edit on Additional Dependencies and enter all the lib files' names which are ended with d (for an example opencv_core2410d.lib) inside your lib directory that you mentioned on "Setting Opencv library directory" step. Here stands for Debug.
Now all the properties have set to build an opencv project in Debug mode. If you need to build in Release mode you have to create a new separate property sheet under Release | Win32  and follow same steps as I mentioned above to set properties except 3rd step. Here you have to enter all the lib file names which are not ended with d (for an example opencv_core2410.lib)

Step 4 - Save and reuse Property sheets

Now click on Save button on the Property Manager to save your property sheets. Then you can find your property sheets where you saved (Here project folder).
Now assume that you have created a new Visual Studio OpenCV project, then you don't need to set all these properties again and again. You just needed to import these properties from these saved property sheets by clicking on "Add Existing Property Sheet..". So all the properties will be automatically set for your project. This is too easier than just setting these properties repeatably.
Thanks for reading this article and hope this will increase your developing speed !


Continue Reading...

Create GUI with Gtkmm - Glade with gtkmm

Previous post introduced the Gtkmm library and eclipse IDE for gtkmm development. As I mentioned at there, there are two possible ways to design gtkmm GUI either from code or Glade UI designer. I believe (and most of people believe) that Glade UI designer is the easiest way to create GUI for gtkmm development. Glade has a very user friendly environment to design and create GUI and finally the created GUI can be export as a xml file with two different formats as GtkBuilder and libglade. For this and future examples I am willing to use GtkBuilder format.
Now let's create a simple GUI from Glade. First you have to install Glade on your system, you may use synaptic package manager or Ubuntu software center to install it.

When you run Glade you may see the following window as the main window of Glade.




As you can see, left hand side of the window includes the palette which has all the gtkmm widget that glade support, and right hand side includes the properties of the selected widget and all the widgets list as a hierarchical list.

Every gtkmm GUI needs a top level window. Therefore first of all add a 'Window' from the palette, then you can add more widgets to the window. Also there is a widget type called 'Containers', containers can have one or more widgets on it. Therefore you should add proper containers to the empty window to include more widgets. For this example first add 'Vertical box' to window with 2 items. Then I added 'Label' to first position and 'Horizontal box' with 2 items to second position of vertical box. Likewise I have created the following GUI and saved it as GtkBuilder file format with the file name “gui.glade”. Also I have changed names of some widgets to make design file more understandable. The xml file for Glade GUI can be found at the end of this article for downloads.




Now let's write a C++ code for this GUI. As we all know C++ is a OOP language, but still we did not use the advantage of the OOP behavior for our gtkmm codes. Now let's see how to encapsulate all the things which are related to specific gui into one class.

First add new class to your project by right click on the eclipse project and selecting new class from the pop-up menu. It will create two file on the project's src folder as header file and source file. Copy following code to header (.h) file.

#include <gtkmm.h>

class FrmMain : public Gtk::Window{
protected:
    Glib::RefPtr<Gtk::Builder> builder;
    Gtk::Button *btnOk;
    Gtk::Button *btnCancel;
    Gtk::Label *lblNotice;

public:
    FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);//constructor

protected:
    //signal handlers
    void on_ok_button_clicked();
    void on_cancel_button_clicked();
};

Code explained

class FrmMain : public Gtk::Window{
FrmMain is the class name and this class was inherited Gtk::Window class which enable to use FrmMain class as a Gtk window.

Glib::RefPtr<Gtk::Builder> builder;
Gtk::Button *btnOk;
Gtk::Button *btnCancel;
Gtk::Label *lblNotice;
These are the widget variables which enable you to execute some operations on that. Here, builder variable is essential to import and load xml file to our code.

FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);//constructor
This is the constructor of the class. The parameters defined in here are essential to initiate the Gtk::Window and Gtk::Builder.

void on_ok_button_clicked();
void on_cancel_button_clicked();
These are the declarations for signal handlers for the signal which are emitted by widgets of the GUI  (Such as event handlers in Java or C#).

The source file for the above header file will be,

#include "FrmMain.h"

using namespace Gtk;

FrmMain::FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) :
    Gtk::Window(cobject), builder(refGlade){

    builder->get_widget("btnOk", btnOk);
    builder->get_widget("btnCancel", btnCancel);
    builder->get_widget("lblNotice",lblNotice);

    btnOk->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
    btnCancel->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));

}


void FrmMain::on_ok_button_clicked(){
    lblNotice->set_text("OK clicked");
}

void FrmMain::on_cancel_button_clicked(){
    lblNotice->set_text("Cancel clicked");
}

Code explained

FrmMain::FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) :
    Gtk::Window(cobject), builder(refGlade){
The constructor, initiate by calling super class constructor as Gtk::Window(cobject) and builder as builder(refGlade).


builder->get_widget("btnOk", btnOk);
builder->get_widget("btnCancel", btnCancel);
builder->get_widget("lblNotice",lblNotice);
These code lines will assign widgets from xml to variables which are declared in header file. (btnOk, btnCancel and lblNotice are the names which I assigned for widgets from Glade).  get_widget function will allows you to get widgets from xml file to your variables. So you can use these variable to manipulate GUI's widgets as your wish.


btnOk->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
btnCancel->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));
These code lines will connect signal handlers from xml file to your functions. That's mean when you click on btnOk button it will call the function  on_ok_button_clicked on your source code. So you can include your codes to execute when click on the button. But you can not change the the return type and parameter list of these functions as your wish. There are predefined formats for each signals. You can refer the format from the source of the signal. To navigate to the source of the signal you can click on the 'signal_clicked' while pressing on ctrl key on eclipse IDE. You may see the code like this,

  Glib::SignalProxy0< void > signal_clicked();

Here zero mean no parameters and void means return type is void. Let's see another example,

  Glib::SignalProxy1< bool,GdkEventButton* > signal_button_press_event();


Here 1 mean one parameter with the type of GdkEventButton* and bool return type. Therefore your function will be,

bool on_my_button_press_event(GdkEventButton* event){
}


void FrmMain::on_ok_button_clicked(){
    lblNotice->set_text("OK clicked");
}

void FrmMain::on_cancel_button_clicked(){
    lblNotice->set_text("Cancel clicked");
}

Now these are the code for signal handlers. Each one will set a specific text to lblNotice label.

So our encapsulated class is ready for execution. But where is the place to import or load xml file to the project by giving the file name of the xml file? This task perform on the main function of the project as,

Main kit(argc,argv);
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("gui.glade");

FrmMain *frm = 0;
builder->get_widget_derived("frmMain", frm);
kit.run(*frm);

Code explained

Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("gui.glade");
This will load all xml (glade) file to builder variable and allow to use the file as a gtk builder.


FrmMain *frm = 0;
builder->get_widget_derived("frmMain", frm);
kit.run(*frm);
get_widget_derived function allow to load a gtk widget from xml file to the derived class which we already implemented. Then the derived object can be use to run the main loop of the gtk.

If you run the code, you will see the result as,

when you click on OK and Cancel button the text of the label will change accordingly.

So now you can encapsulate all the variables, functions and structs, etc... to a class through this way. Also this will enable re-usability of the code.

The complete source code can be download here (with the glade xml file).


Continue Reading...

Create GUI with Gtkmm - Setup Eclipse for Gtkmm

gtkmm is the official C++ interface for the popular GUI library GTK+. You can create user interfaces either in code or with the Glade User Interface designer, using Gtk::Builder.
Still you can use gtk on C++, but C++ is the Object Oriented Programming language then Gtkmm enable you to use some OOP techniques such as inheritance, polymorphism, etc... Also enable you to use standard C++ libraries on Gtkmm calls. Also gtkmm can be use to create GUI in C++ with the large number of widgets which you need to decorate your GUI.

I am willing to write a series of articles/tutorials about Gtkmm and its variance widgets with practical examples. Because I used gtkmm for my final year project and I would like to share the knowledge that I garbed with you all. This article describe the initial steps that you should follow to setup gtkmm library on Ubuntu and configure eclipse for gtkmm developing. I am using Eclipse Helios on Ubuntu 11.04 (64-bit).

Step 1 (Install required packages)
As you know there are several ways to install packages on Ubuntu. I am using Synaptic package manager for that.
So open synaptic from application menu and search for gtkmm-dev and install the latest version from the search result. I have installed libgtkmm-2.4-dev package. When you install synaptic will indicate some dependencies such as gtk++, install them all to complete the installation. I hope that you have the working eclipse with CDT (C/C++ Development Tooling).


Step 2 (Setup Eclipse for Gtkmm)
I am using CDT installed Eclipse IDE‌ for C++ developments. Because it has more features which are more helpful to developer to write programs effectively and rapidly.
Eclipse needs to be setup in order to create gtkmm project. Eclipse needs to complete these setups to compile the program successfully and fill the auto complete menu with all the functions, variables, data types, etc...
Initially you need to select Linux GCC as the toolchain when you create a C++ project on eclipse.
  1. Right click on the project that you need to be configure and select Properties from the menu.
  2. Expand C/C++ Build from the left side pane and click on Settings.
  3. Then click on GCC C++ Compiler.
  4. Paste following command line options between ${COMMAND} and ${FLAGS} to Command line pattern: text box.
    `pkg-config --cflags --libs gtkmm-2.4`
    Note - 2.4 holds the installed version, replace it with your version, if you installed different version.

    Now you may have the full text of the Command line pattern as,
    ${COMMAND} `pkg-config --cflags --libs gtkmm-2.4` ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
  5. Click on GCC C++ Linker and follow the same procedure as previous step.
  6. Now click on Includes under GCC C++ Compiler.
  7. Add include paths to the list and let eclipse find the header files on these paths. Click on add button and add following paths to the list. You should change the location by considering your location which includes installed on and version.

    /usr/include/gtkmm-2.4
    /usr/include/gdkmm-2.4
    /usr/include/glibmm-2.4

    Somehow finally you should include paths for gtkmm, gdkmm and glibmm libraries header files.

Now Eclipse ready for gtkmm development. Let's write a simple testing program to check the gtkmm.

First you should include following header files to the program. As,
#include <gtkmm.h>

Your main function should look like this,

int main(int argc, char **argv) {
    Gtk::Main kit(argc,argv);//The constructor for this object initializes gtkmm
    Gtk::Window frmMain;

    kit.run(frmMain);

    return 0;
}

Code explained,
All the gtkmm programs accepts command line arguments list as above (int argc, char **argv). Therefore all the gtkmm programs should follow the same argument list as describe in here.

Gtk::Main kit(argc,argv);//The constructor for this object initializes gtkmm

This line will initialize the basic gtkmm functionalities and let program to run gtkmm functions. Also checks the arguments passed to your application on the command line, looking for standard options such as -display.


Gtk::Window frmMain;

This will create a new widget of Gtk::Window type as frmMain to hold the main window of the program.


kit.run(frmMain);

This is the main loop of gtkmm and let user to use the widgets. This line will display the window which we already created.

You can download the complete source code of this testing program. Resultant of the program is an empty window as,

Next article will describe the OO behavior of gtkmm and introduce the Glade UI designer for gtkmm.
Continue Reading...

Cteate Stack in C++ using template

Stack is a data structure that allows access to only one data item at a time. If you remove this data item from the stack you can access to the next to last data item of the stack. Also stack perform a Last-In-First-Out(LIFO) operation on the stack. You may find more on stack here.

I will explain basic stack operations and then let's move to code.

Push - Insert a data item to the top of the stack.

Pop - Remove a data item from the top the stack.

Peek - Retrieve the data item from the top of the stack.

Other stack operations can be understand by just looking at the code simply.




This is the stack created by using template of C++. So that you can set any data or class type for stack data. Further more this post will answer the question, How to create template stack in C++?

The Stack.h source file is,

#include <stdlib.h>

#ifndef STACK_H_
#define STACK_H_

template<class T> class Stack{

private:
    unsigned int maxSize;
    T *stackData;
    int top;

public:
    Stack(int size){
        stackData = new T[size];//to hold the T ‌type data items
        top = -1;//no items on the stack
        maxSize = size;//set maximum size that stack can hold
    }


    virtual ~Stack(){}

    int count(){
        return top + 1;
    }


    bool isEmpty(){
        return top == -1 ? true : false;
    }


    bool isFull(){
        return top == maxSize - 1 ? true : false;
    }


    T* peek(){
        if(!isEmpty())//check for empty
            return &stackData[top - 1];
    }


    T* pop(){
        if(!isEmpty()){
            top -= 1;//decrease the top by 1 to indicate the delete
            return &stackData[top];//return deleted item
        }
        return NULL;
    }


    void push(T* item){
        stackData[top++] = *item;//insert to data array and increase the top by one
    }
};


#endif /* STACK_H_ */

Then the demonstration code,

#include <iostream>
#include "Stack.h"

using namespace std;

int main() {

    int data;
    Stack<int> intStack(10);//create integer stack with maximum 10 items

    //insert data to stack
    data = 1;
    intStack.push(&data);
    data = 2;
    intStack.push(&data);
    data = 3;
    intStack.push(&data);
    data = 5;
    intStack.push(&data);

    //get top item
    cout << *intStack.peek() << endl;

    intStack.pop();
    intStack.pop();

    //get top item
    cout << *intStack.peek() << endl;
   
    return 0;
}


I expect this will help anybody who want to create stack with the template!

Continue Reading...

Opencv 2.4.1 instalation libpng error

Now I am hardly working on my research project, It uses Opencv for image processing. Then I heard about opencv latest version released (2.4.1). This post is about an error that I got when I was going to install Opencv 2.4.1. This post does not explaining all about Opencv installation. If you need complete installation guide, just google it.

The error that I got when compiling the Opencv source is,

Linking CXX shared library ../../lib/libopencv_highgui.so
/usr/bin/ld: /usr/local/lib/libpng.a(
pngget.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libpng.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make[2]: *** [lib/libopencv_highgui.so.2.4.
1] Error 1
make[1]: *** [modules/highgui/CMakeFiles/
opencv_highgui.dir/all] Error 2
make: *** [all] Error 2

When I got this error I search on google but I could not find any solution for that. Here is the solution that I suggest and it succeed  for me.

According to my point of view this can be occurred version mismatch between Opencv's libpng and libpng installed on your system. But there is a libpng already included in opencv source download. So you can use that libpng to compile opencv source.

Solution
The error saying about libpng package therefore if you get this error too, you should set a flag BUIL_PNG = on when configure the cmake make file generation process. This allow opencv to compile its source using libpng source that include in the opencv source directory. I used cmake GUI to generate make file on Ubuntu. Here you can easily set that flag on as you can see on following figure.



That's it now you can compile opencv without this error.
So happy opencv coding!

Continue Reading...