Az OpenCV remek képelemző API, de a képeket meg is kell jeleníteni, sőt az sem nagy elvárás, hogy interaktívan változtassuk az elemzés során alkalmazott paramétereket. Szükség van tehát egy grafikus könyvtárra, ami biztosítja számunkra az elemeket. A highgui.h fejléc állomány biztosít számunkra egy igen limitált kereszt platformos elemgyűjteményt, de ha komoly alkalmazásokat akarunk fejleszteni, akkor sokkal több grafikai elemre lesz szükségünk.
Itt jön képbe a QT, ami egy remek kereszt platformos GUI keretrendszer. Jó lenne a kettőt együtt használni.
Alapvetően, ha mindkét könyvtárat linkeljük alkalmazásunkhoz, már használhatjuk is őket. Például készítünk egy ablakot, menükkel, majd a kép megjelenítésnél átváltunk a highgui-ra és azt használjuk. A módszer működik, nagyon ronda és kényelmetlen. Jobb lenne a két API-t közelebb hozni egymáshoz.
Alapvetően két olyan terület van, ahol adatokat kell átadni egyik könyvtárból a másikba. Az egyik a szöveges adatok, másik a képi információk.
Sztringek
Mint minden valamire való C++ könyvtárnak, úgy a QT-nek is és az OpenCV-nek is saját sztring osztálya van és egyik sem kompatibilis a másikkal. A QT QString osztályából könnyen csinálhatunk cv::string-et a következő módon:
void load(QString filename){
Mat raw = imread(filename.toStdString());
}
Képek
Az OpenCV alapvetően a cv::Mat osztályt használja a képek tárolására. QT esetén több, különböző osztály tárolhat képet, attól függően, mi a célunk. Ha rajzolni akarunk, a QGraphicsScene osztályt használhatjuk. Ez csupán egy felület, ahová rajzolhatunk. Ha meg is akarjuk jeleníteni, szükségünk van egy felhasználói felületre is. Ez a QGraphicsView. Az OpenCV viszont csak bitképekkel dolgozik, ehhez az adatstruktúrához a QImage áll legközelebb.
Tehát ha az alkalmazásunk meg akarja jeleníteni a képeket, a következőt kell tennünk: Az OpenCV Mat osztályából a byte adatot át kell másolnunk egy QImage-be, amit elhelyezünk egy QGraphicsScene-ben, amit megjelenítünk a QGraphicsView-val. Lássuk az implementációt!
Size s = raw.size();
QImage qtimage(raw.data, s.width, s.height, QImage::Format_ARGB32);
Az adat formátuma a legkényesebb lépés. Ha rosszul választjuk meg, jó esetben hibás színeket kapunk, rossz esetben lefagy az alkalmazás. Sajnos nem minden OpenCV képformátumhoz találunk QT megfelelőt. A legkevesebb probléma a szürke árnyalatos képeknél van, azokat QImage::Format_Grayscale8 opcióval használhatjuk.
Van még egy rossz hírem. QImage nem adható QGraphicsScene-hez. Szükség van egy közvetítő osztályra a QPixmap személyében:
QGraphicsScene scene;
scene.addPixmap(QPixmap::fromImage(qtimage));
Végezetül jöhet a megjelenítés:
ui->graphicsView->setScene(&scene);
ui->graphicsView->show();
A neten található más megoldások byte-onként másolják az adatot, ami jó megoldás lehet, ha nem támogatott képformátumot használunk. Ellenkező esetben a fenti megoldás gyorsabb eredményt ad.