views:

2597

answers:

4

I want to use OpenCV's image processing functions, but not the OpenCV GUI. I'm using OpenCV 2.0. I will use either Qt4 or WxWidgets for GUI functions. I compile with VC++ 2008 Express (VC++ 9.0).

I guess it breaks down to two or three questions:

  1. Is it necessary to do something to disable OpenCV's higui so it does not interfere with the preferred GUI library, and if so, how?

  2. How to convert an OpenCV image into something (bitmap?) that the preferred GUI can display (and perhaps save)?

  3. (Optional) How to convert an image that was loaded using the preferred interface into a form that OpenCV can use?

A: 

Well I don't know much about OpenCV, but I work with wxWidgets alot.

I highly recommend wxWidgets simply because of its intuitive structure and code layout.

Also, QT is only available under the LGPL on Windows, so licensing may be an issue. wxWidgets can be used in commercial projects without restrictions.

As for converting images back and forth, wxWidgets has a large number of classes/functions for working with images.

George Edison
The only issue I see with a LPGL'ed QT (either on Windows or Linux, doesn't matter) is **IF** Jive change something in the QT library and don't want to share his changes. It's a no-go. Other than that, there is no licensing issue to be afraid of.
esavard
+1  A: 

Is it necessary to do something to disable OpenCV's higui so it does not interfere with the preferred GUI library, and if so, how?

Answer: I don't see why it should not be doable or it is a poorly designed library (which I don't think OpenCV is).

For your other questions (and the "How" of question 1), I did a quick search on QtCentre and found an interesting thread about OpenCV integration with Qt. There is some source code examples that you can look at.

If you don't find what your are looking for in that thread you can start a new one.

Or google for OpenCV integration in Qt or search on Google Code, there is some projects using both Qt and OpenCV (OpenCV Stereo Vision is one).

Good luck.

esavard
A: 

I have made a little progress. The GUI part of OpenCV does seem to stay out of the way. I have even used it in a WxWidgets application to show an image, and nothing bad seemed to happen. That was on a Windows XP box using VC++ 2008. The only interaction that OpenCV/highGUI appears to have with the windowing system is to make direct Windows API calls and to monitor the event queue for keyboard events, which it passes on.

I'm working on how to convert from OpenCV images to WxWidgets images and back. A big help you guys are. :-)

Jive Dadson
+1  A: 

Okay. I've got the answer to my own question for WxWidgets. One key is not to fight openCV City Hall about RGB sequence. OpenCv really likes "BGR". WxWidgets uses "RGB" only. The opencv data structure has a field for byte sequence, but it is seldom honored. Even the highGui function (on MS Windows) that displays an image will put up spectacularly blue tangerines if the byte sequence is set to "RGB". I stubbornly fixed that bug in my local installation, but other operations failed also. So, I just sigh and set the byte order on the opencv side to "BGR" and do the byte swapping as necessary.

The C++ code below requires that the openCV images that it converts to wxImages are RGB, sequence "BGR", 8 bit depth and 3 interleaved channels, and have width_step = width*3. The routines don't check compatibility. Use at your own peril. A ready-for-primetime version would provide for regions of interest (ROI) and other fanciness.

#include "wx/wx.h"
#include "cv.h"
#include "highgui.h" // Optional


void copy_and_swap_rb(char *s, char *d, int size) {
    // Copy image data source s to destination d, swapping R and B channels.
    // Assumes 8 bit depth, 3 interleaved channels, and width_step = width*3
    const int step = 3;
    char *end = s + size;
    while (s<end) {
        d[0] = s[2];
        d[1] = s[1];
        d[2] = s[0];
        d += step; s += step;   
    }
}

void wx2cv(wxImage &wx, IplImage *ipl) {
    // Copy image data from wxWidgets image to Ipl (opencv) image
    // Assumes ipl image has seq "GBR", depth 8, and 3 channels, and 
    // has the same size as the wxImage, and width_step = width*3.
    copy_and_swap_rb((char*)wx.GetData(), ipl->imageData, ipl->imageSize);
}

void cv2wx(IplImage *ipl, wxImage &wx ) {
    // Copy image data from Ipl (opencv) image to wxImage
    // Assumes ipl image has seq "GBR", depth 8, and 3 channels, and 
    // has the same size as the wxImage, and width_step = width*3.
    copy_and_swap_rb( ipl->imageData, (char*)wx.GetData(),   
                      wx.GetWidth()*wx.GetHeight()*3);
}

IplImage *cv_from_wx(wxImage &wx) {
    // Return a new IplImage copied from a wxImage. 
    // Must be freed by user with cvReleaseImage().
    IplImage *ret = cvCreateImage(cvSize(wx.GetWidth(), wx.GetHeight()), 
                                  IPL_DEPTH_8U, 3);
    wx2cv(wx, ret);
    return ret;
}

wxImage wx_from_cv( IplImage *cx) {
    // Return new wxImage copied from a compatible IplImage.
    // Assumes ipl image has seq "GBR", depth 8, and 3 channels
    // Fear not. The copy on return is cheap; does not deep-copy the data.
    wxImage wx(cx->width, cx->height, (unsigned char*) malloc(cx->imageSize), false);
    cv2wx(cx, wx);
    return wx;
}
Jive Dadson
This seems to work for RGB image. What if I have a greyscale IplImage?
Sunny