Port a c++ app to qtgui?



  • Hello there,

    I have a c++ app with opencv.
    It has a complex face recognition algorithm.
    It uses c++ to make the gui itself.
    we want to have this app as a qtgui app.

    i've imported the project to qt creator as a c++ app...works fine

    but we need the gui to be qt widgets and the backend to stay the same.

    i found this :
    http://qt-project.org/doc/qt-5.0/qtdoc/portingcppapp.html
    but the app has no qt at all, just c++. a search in this forum didnt get any results either..

    the project is long and complex with many header files....

    at first i´ve tried to see if there are qt opencv face recognition apps already done and just adapt them to our needs, but it seems the ones available,
    like this one : https://gitorious.org/qt-opencv/qt-opencv/source/a9c94d1ea955b287f8a1f5173d36814ab4a9eedd:
    only detect faces and we need to recognize using either eigenfaces (lbp cascades) or fisher faces so that we can save users, like a login page...

    so it´s been difficult to adapt that app with our algo, so i´ve reverted to simply port the original app to qtgui.

    how do i go about with the qt creator to creating widgets? its my first time using qt creator...

    (i´m thinking that i would need to remove the image utils files i have, and then draw in the designer the gui i need, wihtout breaking the backend: detects a face, pre-process it and then after detection is established, with the algos trains to recognize the face, save that user and loop again)

    !http://i.imgur.com/CYfHItF.png(c++ app in qt, need the gui to be native qt)!
    c++ app in qt, need the gui to be widgets

    the source code which we based off (we added to it to save the faces in another folder and some performance enhancements) can be found here:
    https://github.com/MasteringOpenCV/code/tree/master/Chapter8_FaceRecognition

    thanks for any suggestions.

    ps. we are working with ubuntu and then we will take the app to an i.MX board that has ubuntu, and other modules are done in qt thus why i want this app in qt, imagine this as a login page for other stuff...



  • ok so i ve taken the time to do more things...

    so far i ported the app to qt as a c++ app
    https://github.com/djvita/Profile_Detection_V5-QT
    it runs fine but its not qt as the mentor told me,

    and now Im trying to do so as a qt widgets app, bu we are still in the same dilemma, to grab the frame and post it to a qimage in a qwidget frame, with the algo working once detection is established...
    right now my only errors are in main

    main.cpp:565: undefined reference to `preprocessFace::getPreprocessedFace(cv::Mat&, int, cv::CascadeClassifier&, cv::CascadeClassifier&, cv::CascadeClassifier&, bool, cv::Rect_<int>, cv::Point_<int>, cv::Point_<int>, cv::Rect_<int>, cv::Rect_<int>*)'

    main.cpp:702: undefined reference to `recognition::learnCollectedFaces(std::vector<cv::Mat, std::allocatorcv::Mat >, std::vector<int, std::allocator<int> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'

    main.cpp:722: undefined reference to `recognition::reconstructFace(cv::Ptrcv::FaceRecognizer, cv::Mat)'

    but they are defined! constructor in .h, function in .cpp and they are included in main; it must be because its a Mat function and not a regular function.
    reading from another thread it says its the compiler, but all the files are linked in the .pro:

    #-------------------------------------------------

    Project created by QtCreator 2014-01-07T19:38:46

    #-------------------------------------------------

    QT += core gui

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = profiledetection-direct
    TEMPLATE = app

    SOURCES += main.cpp
    mainwindow.cpp
    detectobject.cpp
    preprocessface.cpp
    recognition.cpp
    ImageUtils_0.7.cpp

    HEADERS += mainwindow.h
    detectobject.h
    preprocessface.h
    recognition.h
    ImageUtils.h

    FORMS += mainwindow.ui

    OpenCv Configuration

    INCLUDEPATH += /usr/local/include/opencv
    LIBS += -L/usr/local/lib
    LIBS += -lopencv_core
    LIBS += -lopencv_imgproc
    LIBS += -lopencv_highgui
    LIBS += -lopencv_ml
    LIBS += -lopencv_video
    LIBS += -lopencv_features2d
    LIBS += -lopencv_calib3d
    LIBS += -lopencv_objdetect
    LIBS += -lopencv_contrib
    LIBS += -lopencv_legacy
    LIBS += -lopencv_flann
    LIBS += -lopencv_nonfree
    LIBS += pkg-config opencv --libs

    here is my progress so far:
    https://github.com/djvita/profiledetection-direct

    but i fear once i have no errors, i will have a bug which no frame will be displayed
    can you tell me how i can go about doing this? if it needs a total overhaul, at least a list of thing to do would be great.



  • EDITED
    Seems like I just missed your intentions, so I'm just leaving out my previous answer. I wish you good luck with that ;)


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Which sources are you referring to ? Profile_Detection_V5-QT or profiledetection-direct ?



  • @SGaist thanks I'm liking Qt, knew about qt a bit and was intrigued by the platform since i had an N8...I refer to profiledetection-direct app.

    one of my colleagues referred me to check if the .o files have the functions; they do indeed:

    /build-profiledetection-direct-Clone_of_Desktop-Debug$
    nm recognition.o | grep reconstructFace
    got as output
    000008be TZ15reconstructFaceN2cv3PtrINS_14FaceRecognizerEEENS_3MatE

    so the machine code does have the function....

    as sugegsted, i tried linking the entire path of the .o to the .pro file and it gave errors of my other functions being redefined; and these same functions being not referenced...

    still don't know what to do to remove that error and proceed on to seeing if this works....

    T3STY, I saw your original answer that came through my email so I will paste it in case anyone ever searches and they can see your answer, I liked it and will apply some things, now I have to check with my friends that have other modules in qt using other tech (such as qtGooglemaps, smartphone sensors to change screens, and even a primesense for motion gestures) how the UI would be linked, as they want one HUB for everything; as far as I saw, the UI is completely removed from the backend, how the original author made it, as he wrote:

    "However, as the face recognition system in this chapter is designed for learning as well as practical fun purposes, rather than competing with the latest research methods it is useful to have an easy-to-use GUI that allows face collection, training, and testing, interactively from the webcam in real time. So this section will provide an interactive GUI providing these features.
    The reader is expected to either use this provided GUI that comes with this book, or to modify the GUI for their own purposes, or to ignore this GUI and design their own GUI to perform the face recognition techniques discussed so far.
    As we need the GUI to perform multiple tasks, let's create a set of modes or states that the GUI will have, with buttons or mouse clicks for the user to change modes:

    • Startup: This state loads and initializes the data and webcam.

    • Detection: This state detects faces and shows them with preprocessing, until the user clicks on the Add Person button.

    • Collection: This state collects faces for the current person, until the user clicks anywhere in the window. This also shows the most recent face of each person. User clicks either one of the existing people or the Add Person button, to collect faces for different people.

    • Training: In this state, the system is trained with the help of all the collected faces of all the collected people.

    • Recognition: This consists of highlighting the recognized person and showing a confidence meter. The user clicks either one of the people or the Add Person button, to return to mode 2 (Collection).

    To quit, the user can hit Escape in the window at any time. Let's also add a Delete All mode that restarts a new face recognition system, and a Debug button that toggles the display of extra debug info. We can create an enumerated mode variable to show the current mode.
    "

    The GUI is written in openCV, some of the drawings are in C functions, using opencv1 like IplImage, and some are in 2.x , using C++ functions like Mat



  • here's T3STY's original reply:

    "If you're looking for a click here to port in Qt button, there is no way
    you can find it.
    Porting such application to Qt is not really hard, but does require a lot of work. It depends on how much the back-end relies on the current GUI; if the integration level is "a lot" I'd suggest a total re-write of the application because a port of it (not just to Qt, but to any other toolkit) will be a real drama where you look for replacement functions in the new toolkit, but such replacements might not exist or the same thing is achieved differently.
    In case your back-end is separated enough from the current UI the port is possible with not much headache. Next I'll try to describe a few steps that you should do for the porting, but I want to pinpoint that I'm not a Qt expert at all, these are just my thoughts on how you should proceed. Other (more expert) people may give you any better advices.
    1) prerequisites
    As a first step to do you should make sure that your back-end code is
    (almost) properly working on its own and does not rely on any GUI objects you currently have. Even more, if possible, the back-end code should not rely on GUI code at all (that's the definition of back-end code). Once you made sure the back-end is properly working on its own, step further.
    2) learning Qt -
    Since you're asking help here for porting the application to Qt I suppose you have little or no knowledge about Qt, so I highly suggest to start experimenting with Qt and its "widgets":http://qt-project.org/doc/qt-5.1/qtwidgets/widget-classes.html#the-widget-classes to learn how you could use every available widget in your project. Also, learn well how to use the "signals and slots":http://qt-project.org/doc/qt-4.8/signalsandslots.html system of Qt because it's highly integrated in Qt's widgets classes and you'll often need to use it to create interactions between back-end and front-end. It is possible to use other signals and slots systems from other toolkits, but looks to me like a more advanced task because it requires enough knowledge of Qt's signals and slot system. Last, but not least, have a look at the "QtCore":http://qt-project.org/doc/qt-5.1/qtcore/qtcore-index.html module which includes all the "Qt data types":http://qt-project.org/doc/qt-5.1/qtcore/datastreamformat.html and "container classes":http://qt-project.org/doc/qt-5.1/qtcore/containers.html that the widgets use; you'll rely on these pretty much everywhere in Qt.
    3) porting the back-end
    Porting the whole back-end to Qt is not necessary but in many cases having Qt data types in your back-end will simplify the back-end management in Qt.
    Instead of const char strings use Qt's QString class, instead of C++'s standard arrays maybe use a QList or a QVector. I repeat, this step isn't necessarily required but if you're going to use Qt it will help you a lot.
    If you don't wish to do that, no worries; Qt has implemented a lot of
    methods in its classes that can convert data from C++ standard types to Qt data types and the other way around.

    At this point you can step further in two different ways: either designing
    the GUI and then making it interact with the back-end, or designing the widgets that the back-end will have to use and then put them together in the GUI. Personally, I prefer the first method because the visual appearance of an application very often determines other code that should be added (or removed) in the back-end. The second method is good as well but it often results in a GUI you don't really like and consequently in further changes in both the front-end and the back-end. Your choice here though, for a simple porting the second method might be good enough to build your first GUI and in future you may get back and redesign it from scratch.

    4 or 5) design the GUI
    It is easy enough to make a GUI in Qt. Start figuring out which widgets could be helpful to your GUI and start working on coding the GUI only. Just because it's a GUI it doesn't mean it has to work with the back-end; in areas where your back-end code should draw an image or other things just put placeholder widgets. In this step you only have to make sure that all the widgets you use interact well with each other, but also, you have to make sure they have the right place to put the back-end code into. Use "qDebug":http://qt-project.org/doc/qt-5.0/qtcore/qdebug.html messages instead of function calls to the back-end and simulate the back-end response to them. You will not achieve a fully working GUI where simply putting the back-end functions will make the whole application work correctly, but you'll know this way what is working or what you're required to do in order to make it work. Make sure the data types from the Widgets you use are compatible to the back-end required data types, and the other way around.

    5 or 4) connect the GUI to the back-end
    Connecting widgets to your back-end code is going to be both easy and hard. It will be easy since you already designed the GUI and you know pretty much which part of the back-end is required to interact with which widgets; the hard part is making them actually interact. Start by adding the main back-end functions to your GUI and check them to work properly. Leave (secondary) Widgets of non-relevant tasks (like the ones used for settings or to save/load files) for later and make sure the main back-end functions (like the ones used to show the webcam captured image) work properly. Get back to the secondary widgets once the main is working fine.

    I hope this will help you in porting the application in Qt. If you have any
    specific questions just ask ;)
    "
    One condition though is to use 4.8.7 libraries...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.