17 Stimmen

OpenCV mit anderen GUI (wie Qt oder WxWidgets) auf Win32 VC++

Ich möchte die Bildverarbeitungsfunktionen von OpenCV nutzen, aber nicht die OpenCV-GUI. Ich verwende OpenCV 2.0. Ich werde entweder Qt4 oder WxWidgets für die GUI-Funktionen verwenden. Ich kompiliere mit VC++ 2008 Express (VC++ 9.0).

Ich schätze, dass es auf zwei oder drei Fragen hinausläuft:

  1. Ist es notwendig, etwas zu tun, um OpenCV's higui zu deaktivieren, so dass es nicht mit der bevorzugten GUI-Bibliothek stört, und wenn ja, wie?

  2. Wie konvertiert man ein OpenCV-Bild in etwas (Bitmap?), das die bevorzugte GUI anzeigen (und vielleicht speichern) kann?

  3. (Optional) Wie konvertiert man ein Bild, das über die bevorzugte Schnittstelle geladen wurde, in eine Form, die OpenCV verwenden kann?

5voto

Jive Dadson Punkte 15912

Okay. Ich habe die Antwort auf meine eigene Frage für WxWidgets. Ein Schlüssel ist, sich nicht mit OpenCV City Hall über die RGB-Sequenz zu streiten. OpenCv mag "BGR" wirklich. WxWidgets verwendet nur "RGB". Die opencv-Datenstruktur hat ein Feld für die Byte-Reihenfolge, aber es wird nur selten beachtet. Sogar die highGui-Funktion (unter MS Windows), die ein Bild anzeigt, zeigt spektakulär blaue Mandarinen an, wenn die Byte-Sequenz auf "RGB" eingestellt ist. Ich habe diesen Fehler in meiner lokalen Installation hartnäckig behoben, aber auch andere Operationen schlugen fehl. Also seufze ich nur und setze die Byte-Reihenfolge auf der opencv-Seite auf "BGR" und tausche die Bytes nach Bedarf aus.

Der folgende C++-Code setzt voraus, dass die openCV-Bilder, die er in wxImages konvertiert, RGB, Sequenz "BGR", 8 Bit Tiefe und 3 verschachtelte Kanäle sind und width_step = width*3 haben. Die Routinen prüfen die Kompatibilität nicht. Verwendung auf eigene Gefahr. Eine einsatzbereite Version würde Interessensbereiche (ROI) und andere Spielereien ermöglichen.

#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;
}

5voto

dantswain Punkte 5297

Ich weiß, dass ich sehr spät zu dieser Diskussion komme, aber ich bin gerade zufällig darauf gestoßen. Wie auch immer, ich habe mit OpenCV und wxWidgets zusammen ganz glücklich für ein paar Jahre jetzt, so dass ich dachte, ich würde in pitch:

Ist es notwendig, etwas zu tun, um OpenCV's higui zu deaktivieren, so dass es nicht mit der bevorzugten GUI-Bibliothek stört, und wenn ja, wie?

Im Allgemeinen nicht. Es gibt ein paar Probleme, die bei bestimmten Versionen von OpenCV und Windows auftreten können. Im Großen und Ganzen ist die Integration jedoch sehr reibungslos. Ich verwende wx routinemäßig für mein Frontend y die Teile von highgui, die die Bilderfassung ermöglichen. Ich habe dies auf verschiedenen Versionen von Windows, Ubuntu und OS X getan.

Wie konvertiert man ein OpenCV-Bild in etwas (Bitmap?), das die bevorzugte GUI anzeigen (und vielleicht speichern) kann?

Eine Alternative zum Hin- und Herkopieren zwischen einem wxImage ist es, die Daten des IplImage direkt in eine OpenGL-Textur zu packen und diese auf eine wxGLCanvas zu malen. Ein großer Vorteil dieser Strategie ist, dass man dann mit Standard-OpenGL-Methoden auf der Textur zeichnen kann.

(Optional) Wie konvertiert man ein Bild, das über die bevorzugte Schnittstelle geladen wurde, in eine Form, die OpenCV verwenden kann?

Tun Sie es nicht :) Ich verwende wxFileDialog usw., damit der Benutzer Pfade angeben kann, aber das gesamte Backend ist direkt OpenCV.

(Selbststecker beginnen)

Der Code, den ich dafür geschrieben habe, ist Teil eines Projekts namens MADTraC das ein GUI-/Anwendungs-Framework für Echtzeit-Computer-Vision-Anwendungen ist.

(Ende Selbststecker)

1voto

Etienne Savard Punkte 4621

Ist es notwendig, etwas zu tun, um OpenCV's higui zu deaktivieren, so dass es nicht mit der bevorzugten GUI-Bibliothek stört, und wenn ja, wie?

Antwort: Ich sehe nicht, warum es nicht machbar sein sollte oder es ist eine schlecht gestaltete Bibliothek (was ich nicht glaube, OpenCV ist).

Für Ihre anderen Fragen (und das "Wie" von Frage 1) habe ich eine schnelle Suche auf QtCentre und fand einen interessanten Thread über OpenCV-Integration mit Qt . Es gibt einige Quellcode-Beispiele, die Sie sich ansehen können.

Wenn Sie in diesem Thread nicht finden, was Sie suchen, können Sie einen neuen Thread eröffnen.

Oder googeln Sie nach OpenCV-Integration in Qt oder suchen Sie auf Google Code, es gibt einige Projekte, die sowohl Qt als auch OpenCV verwenden ( OpenCV Stereo Vision ist eine ).

Viel Glück!

0voto

Nathan Osman Punkte 67377

Nun, ich weiß nicht viel über OpenCV, aber ich arbeite viel mit wxWidgets.

Ich empfehle wxWidgets allein schon wegen seiner intuitiven Struktur und seines Code-Layouts.

Außerdem ist QT nur unter der LGPL für Windows verfügbar, so dass die Lizenzierung ein Problem darstellen kann. wxWidgets kann in kommerziellen Projekten ohne Einschränkungen verwendet werden.

Um Bilder hin und her zu konvertieren, hat wxWidgets eine große Anzahl von Klassen/Funktionen für die Arbeit mit Bildern.

0voto

Jive Dadson Punkte 15912

Ich habe einen kleinen Fortschritt gemacht. Der GUI-Teil von OpenCV scheint mir nicht im Weg zu stehen. Ich habe es sogar in einer WxWidgets-Anwendung verwendet, um ein Bild anzuzeigen, und es schien nichts Schlimmes zu passieren. Das war auf einem Windows XP Rechner mit VC++ 2008. Die einzige Interaktion, die OpenCV/highGUI mit dem Fenstersystem zu haben scheint, besteht darin, direkte Windows-API-Aufrufe zu tätigen und die Ereigniswarteschlange auf Tastaturereignisse zu überwachen, die es dann weiterleitet.

Ich arbeite daran, wie man von OpenCV-Bildern zu WxWidgets-Bildern und zurück konvertiert. Ihr seid mir eine große Hilfe :-)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X