123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625 |
- /*
- * NICE-Core - efficient algebra and computer vision methods
- * - libimagedisplay - A library for image and video display
- * See file License for license information.
- */
- #include "core/imagedisplay/ImageDisplay.h"
- #include <iostream>
- #ifdef NICE_USELIB_GLUT
- #include <GL/glut.h>
- #endif
- #include <qcursor.h>
- #include <QFileDialog>
- #include <qapplication.h>
- #include <qpushbutton.h>
- #include <qlineedit.h>
- #include <qcheckbox.h>
- #include <QContextMenuEvent>
- #include <QMouseEvent>
- #include <QMenu>
- #include <core/basics/Exception.h>
- #include <core/basics/FileName.h>
- #include <core/imagedisplay/QtFramework.h>
- #include <core/imagedisplay/ImageDisplayManager.h>
- #include <core/imagedisplay/OverlayColors.h>
- // we need this function for overlays
- #include <core/image/Convert.h>
- namespace NICE {
- ImageDisplay::ImageDisplay ( QWidget* parent, const char* name, Qt::WFlags flags )
- : QGLWidget ( parent, NULL, flags ),
- image ( NULL ),
- colorImageBuffer ( NULL ),
- grayImageBuffer ( NULL ),
- copied ( false ),
- isDragging ( false ),
- buf_overlayImage ( NULL )
- {
- if ( parent == NULL ) {
- ImageDisplayManager::instance().registerWidget ( this );
- }
- updateGL();
- }
- ImageDisplay::~ImageDisplay() {
- //ImageDisplayManager::instance().unregisterWidget(this);
- if ( copied && colorImageBuffer != NULL ) {
- delete colorImageBuffer;
- }
- if ( copied && grayImageBuffer != NULL ) {
- delete grayImageBuffer;
- }
- if ( buf_overlayImage != NULL )
- delete [] buf_overlayImage;
- }
- void ImageDisplay::setImage ( const NICE::ColorImage* _image,
- const bool copy ) {
- frameRateCounter.newFrame();
- if ( frameRateCounter.getCounter() == 0 ) {
- doSetCaption();
- }
- if ( sequenceWriter.get() != NULL ) {
- sequenceWriter->writeColorImage ( *_image );
- }
- int oldImageWidth = 0;
- int oldImageHeight = 0;
- if ( image != NULL ) {
- oldImageWidth = image->width();
- oldImageHeight = image->height();
- }
- if ( copied && grayImageBuffer != NULL ) {
- delete grayImageBuffer;
- grayImageBuffer = NULL;
- }
- isColor = true;
- if ( copy ) {
- if ( copied && colorImageBuffer != NULL ) {
- if ( _image->width() != colorImageBuffer->width()
- || _image->height() != colorImageBuffer->height() ) {
- delete colorImageBuffer;
- colorImageBuffer
- = new NICE::ColorImage ( *_image, NICE::GrayColorImageCommonImplementation::noAlignment );
- } else {
- colorImageBuffer->copyFrom ( *_image, NICE::GrayColorImageCommonImplementation::noAlignment );
- }
- } else {
- copied = true;
- colorImageBuffer
- = new NICE::ColorImage ( *_image, NICE::GrayColorImageCommonImplementation::noAlignment );
- }
- image = colorImageBuffer;
- } else {
- if ( copied && colorImageBuffer != NULL ) {
- delete colorImageBuffer;
- colorImageBuffer = NULL;
- }
- image = _image;
- }
- if ( oldImageWidth != image->width() || oldImageHeight != image->height() ) {
- resize ( image->width(), image->height() );
- }
- updateGL();
- }
- void ImageDisplay::setImage ( const NICE::Image* _image,
- const bool copy ) {
- frameRateCounter.newFrame();
- if ( frameRateCounter.getCounter() == 0 ) {
- doSetCaption();
- }
- if ( sequenceWriter.get() != NULL ) {
- sequenceWriter->writeGrayImage ( *_image );
- }
- int oldImageWidth = 0;
- int oldImageHeight = 0;
- if ( image != NULL ) {
- oldImageWidth = image->width();
- oldImageHeight = image->height();
- }
- if ( copied && colorImageBuffer != NULL ) {
- delete colorImageBuffer;
- colorImageBuffer = NULL;
- }
- isColor = false;
- if ( copy ) {
- if ( copied && grayImageBuffer != NULL ) {
- if ( _image->width() != grayImageBuffer->width()
- || _image->height() != grayImageBuffer->height() ) {
- delete grayImageBuffer;
- grayImageBuffer
- = new NICE::Image ( *_image, NICE::GrayColorImageCommonImplementation::noAlignment );
- } else {
- grayImageBuffer->copyFrom ( *_image, NICE::GrayColorImageCommonImplementation::noAlignment );
- }
- } else {
- copied = true;
- grayImageBuffer
- = new NICE::Image ( *_image, NICE::GrayColorImageCommonImplementation::noAlignment );
- }
- image = grayImageBuffer;
- } else {
- if ( copied && grayImageBuffer != NULL ) {
- delete grayImageBuffer;
- grayImageBuffer = NULL;
- }
- image = _image;
- }
- if ( oldImageWidth != image->width() || oldImageHeight != image->height() ) {
- resize ( image->width(), image->height() );
- }
- updateGL();
- }
- void ImageDisplay::setOverlayImage ( const NICE::Image* overlayImage ) {
- bool alloc = false;
- if ( buf_overlayImage == NULL )
- alloc = true;
- else if ( ( overlayImageWidth != overlayImage->width() ) ||
- ( overlayImageHeight != overlayImage->height() ) )
- alloc = true;
- if ( alloc ) {
- if ( buf_overlayImage != NULL )
- delete [] buf_overlayImage;
- overlayImageWidth = overlayImage->width();
- overlayImageHeight = overlayImage->height();
- // RGBA image: 4 channels
- buf_overlayImage = new unsigned char[ overlayImageWidth *
- overlayImageHeight * 4 ];
- }
- long int k = 0;
- for ( int y = 0; y < overlayImage->height(); y++ ) {
- const unsigned char* end = overlayImage->getPixelPointerYEnd ( y );
- int colstep = overlayImage->columnStepsize();
- for ( const unsigned char* p = overlayImage->getPixelPointerY ( y ); p != end;
- p = ( const unsigned char * ) ( ( ( Ipp8u * ) p ) + colstep ) )
- {
- unsigned char overlayValue = *p;
- unsigned char r, g, b, alpha;
- if ( overlayValue <= 0 ) {
- r = 0;
- b = 0;
- g = 0;
- alpha = 0;
- } else {
- int colorValue = overlayValue % overlayColorTableNumEntries;
- r = overlayColorTable[colorValue][0];
- g = overlayColorTable[colorValue][1];
- b = overlayColorTable[colorValue][2];
- alpha = 255;
- }
- buf_overlayImage[k++] = r;
- buf_overlayImage[k++] = g;
- buf_overlayImage[k++] = b;
- buf_overlayImage[k++] = alpha;
- }
- }
- updateGL();
- }
- void ImageDisplay::repaint() {
- updateGL();
- }
- void ImageDisplay::paintGL() {
- #ifdef NICE_USELIB_GLUT
- setGLProjection();
- if ( image != NULL ) {
- glPixelStorei ( GL_PACK_ALIGNMENT, 1 );
- glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
- glPixelZoom ( ( GLfloat ) width() / ( ( GLfloat ) image->width() ),
- ( ( GLfloat ) - height() ) / ( ( GLfloat ) image->height() ) );
- glRasterPos2f ( 0, height() - 0.5 );
- if ( isColor ) {
- glDrawPixels ( image->width(), image->height(),
- GL_RGB, GL_UNSIGNED_BYTE,
- image->getPixelPointer() );
- } else {
- glDrawPixels ( image->width(), image->height(),
- GL_LUMINANCE, GL_UNSIGNED_BYTE,
- image->getPixelPointer() );
- }
- } else {
- glClearColor ( 0.0, 0.0, 0.0, 0.0 );
- glClear ( GL_COLOR_BUFFER_BIT );
- glFlush();
- }
- if ( buf_overlayImage != NULL ) {
- if ( image == NULL ) {
- glPixelStorei ( GL_PACK_ALIGNMENT, 1 );
- glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
- glPixelZoom ( ( GLfloat ) width() / ( ( GLfloat ) overlayImageWidth ),
- ( ( GLfloat ) - height() ) / ( ( GLfloat ) overlayImageHeight ) );
- glRasterPos2f ( 0, height() - 0.5 );
- }
- glEnable ( GL_BLEND );
- glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- glDrawPixels ( overlayImageWidth, overlayImageHeight,
- GL_RGBA, GL_UNSIGNED_BYTE, buf_overlayImage );
- glDisable ( GL_BLEND );
- glFlush();
- }
- if ( isDragging && drawSelectionRect ) {
- glLineWidth ( 1 );
- glEnable ( GL_LINE_STIPPLE );
- glLineStipple ( 1, 0x00FF );
- glColor4f ( 1, 1, 1, 1 );
- // // Antialiased Points
- // glEnable(GL_POINT_SMOOTH);
- // glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
- // // Antialiased Lines
- // glEnable(GL_LINE_SMOOTH);
- // glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
- glBegin ( GL_LINE_LOOP );
- glVertex2f ( dragX, height() - dragY );
- glVertex2f ( dragX, height() - dropY );
- glVertex2f ( dropX, height() - dropY );
- glVertex2f ( dropX, height() - dragY );
- glEnd();
- glDisable ( GL_LINE_STIPPLE );
- glFlush();
- }
- if ( texts.size() > 0 ) {
- glEnable ( GL_BLEND );
- glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- for ( uint i = 0; i < texts.size(); ++i ) {
- Text& text = texts[i];
- glColor4ub ( text.color[0], text.color[1], text.color[2], 255 );
- float x = float ( text.x ) * float ( width() ) / float ( image->width() );
- float y = float ( text.y ) * float ( height() ) / float ( image->height() );
- glRasterPos2f ( x, height() - y - 0.5 );
- void* font = GLUT_BITMAP_HELVETICA_10;//(*i)->font;
- for ( uint j = 0; j < text.text.size(); ++j )
- glutBitmapCharacter ( font, text.text[j] );
- }
- glDisable ( GL_BLEND );
- glFlush();
- }
- #else
- fthrow(Exception,"GLUT lib not availabe, recompile using GLUT!");
- #endif
- paintGLObjects();
- }
- void ImageDisplay::setGLProjection ( void ) {
- #ifdef NICE_USELIB_GLUT
- glViewport ( 0, 0, width(), height() );
- glMatrixMode ( GL_PROJECTION );
- glLoadIdentity();
- gluOrtho2D ( 0.0, ( GLdouble ) width(), 0.0, ( GLdouble ) height() );
- #else
- fthrow(Exception,"GLUT lib not availabe, recompile using GLUT!");
- #endif
- }
- void ImageDisplay::paintGLObjects ( void ) {
- }
- void ImageDisplay::mousePressEvent ( QMouseEvent* event ) {
- QGLWidget::mousePressEvent ( event );
- startDrag ( event->x(), event->y() );
- }
- void ImageDisplay::mouseMoveEvent ( QMouseEvent* event ) {
- QGLWidget::mouseMoveEvent ( event );
- dragging ( event->x(), event->y() );
- }
- void ImageDisplay::mouseReleaseEvent ( QMouseEvent* event ) {
- QGLWidget::mouseReleaseEvent ( event );
- makeDrop ( event->x(), event->y() );
- float left = dragX * ( image->width() / ( float ) width() );
- float right = dropX * ( image->width() / ( float ) width() );
- float top = dragY * ( image->height() / ( float ) height() );
- float bottom = dropY * ( image->height() / ( float ) height() );
- if ( left > right ) {
- std::swap ( left, right );
- }
- if ( top > bottom ) {
- std::swap ( top, bottom );
- }
- emit rectSelect ( left, top, right, bottom );
- }
- void ImageDisplay::startDrag ( int x, int y ) {
- isDragging = true;
- dragX = x;
- dragY = y;
- dropX = x;
- dropY = y;
- updateGL();
- }
- void ImageDisplay::dragging ( int x, int y ) {
- if ( isDragging ) {
- dropX = x;
- dropY = y;
- updateGL();
- }
- }
- void ImageDisplay::makeDrop ( int x, int y ) {
- if ( isDragging ) {
- isDragging = false;
- dropX = x;
- dropY = y;
- updateGL();
- }
- }
- void ImageDisplay::contextMenuEvent ( QContextMenuEvent* event ) {
- QMenu* popupMenu = new QMenu ( this );
- addExtraMenuItems ( popupMenu );
- popupMenu->addAction("&Save Image", this, SLOT ( menuSave() ), Qt::CTRL + Qt::Key_S);
- popupMenu->addAction("&Restore aspect ratio", this, SLOT ( menuAspectRatio ), Qt::CTRL + Qt::Key_A);
- popupMenu->addSeparator();
- popupMenu->addAction ( "Start &capturing image sequence", this, SLOT ( menuStartCapture() ) );
- popupMenu->addAction ( "Sto&p capturing", this, SLOT ( menuStopCapture() ) );
- popupMenu->exec ( QCursor::pos() );
- delete popupMenu;
- }
- void ImageDisplay::addExtraMenuItems ( QMenu *popupMenu )
- {
- }
- void ImageDisplay::menuAspectRatio() {
- if ( image != NULL ) {
- resize ( size().width(), size().width() * image->height() / image->width() );
- }
- }
- void ImageDisplay::menuSave() {
- QString s = QFileDialog::getSaveFileName(this,
- "Save file dialog",
- "",
- "Images (*.ppm, *.pgm, *.png, *.jpg)");
- if ( s.isNull() ) {
- return;
- }
- NICE::FileName filename ( s.toLocal8Bit() );
- const std::string ext = filename.extractExtension().str();
- const bool extensionOk
- = ( ext == std::string ( ".ppm" ) || ext == std::string ( ".pgm" )
- || ext == std::string ( ".png" ) || ext == std::string ( ".jpg" ) );
- if ( !extensionOk ) {
- if ( isColor ) {
- filename.setExtension ( ".ppm" );
- } else {
- filename.setExtension ( ".pgm" );
- }
- }
- image->write ( filename.str() );
- }
- void ImageDisplay::menuStartCapture() {
- if ( dialog.get() == NULL ) {
- dialog.reset ( new CaptureDialog ( this, "Capture Dialog" ) );
- dialog->setWindowTitle ( "Capture: " + captionBuffer );
- connect ( ( QObject* ) dialog->capture(), SIGNAL ( started() ),
- this, SLOT ( dialogStartCapture() ) );
- connect ( ( QObject* ) dialog->capture(), SIGNAL ( stopped() ),
- this, SLOT ( dialogStopCapture() ) );
- }
- dialog->show();
- }
- void ImageDisplay::menuStopCapture() {
- if ( dialog.get() != NULL ) {
- dialog->capture()->buttonStopClicked();
- }
- }
- void ImageDisplay::dialogStartCapture() {
- sequenceWriter.reset (
- new ImageFileListWriter ( dialog->capture()->directoryName(),
- dialog->capture()->extensionName(),
- dialog->capture()->isBuffered() ) );
- }
- void ImageDisplay::dialogStopCapture() {
- sequenceWriter.reset ( NULL );
- }
- void ImageDisplay::setCaption ( const QString& s ) {
- captionBuffer = s;
- doSetCaption();
- }
- void ImageDisplay::doSetCaption() {
- std::stringstream s;
- s.precision ( 1 );
- s << std::fixed << captionBuffer.toAscii().constData()
- << " (FPS: " << frameRateCounter.getFrameRate() << ")";
- //std::cerr << "ImageDisplay::doSetCaption(): " << s.str() << std::endl;
- QWidget::setWindowTitle ( s.str().c_str() );
- }
- ImageDisplay* displayImage ( const NICE::ColorImage* image,
- const std::string& title,
- const bool copy ) {
- // make sure Qt is initialized
- if ( qApp == NULL ) {
- QtFramework::instance();
- }
- // QWidget* mainWindow = NULL;
- // if (QtFramework::isInstanceInitialized()) {
- // mainWindow = QtFramework::instance().getMainWindow();
- // }
- // ImageDisplay* display
- // = new ImageDisplay(mainWindow, title.c_str(),
- // (unsigned int)Qt::WType_TopLevel);
- ImageDisplay* display = new ImageDisplay();
- display->setCaption ( title.c_str() );
- display->setImage ( image, copy );
- display->show();
- return display;
- }
- ImageDisplay* displayImage ( const NICE::Image* image,
- const std::string& title,
- const bool copy ) {
- // make sure Qt is initialized
- if ( qApp == NULL ) {
- QtFramework::instance();
- }
- // QWidget* mainWindow = NULL;
- // if (QtFramework::isInstanceInitialized()) {
- // mainWindow = QtFramework::instance().getMainWindow();
- // }
- // ImageDisplay* display
- // = new ImageDisplay(mainWindow, title.c_str(),
- // (unsigned int)Qt::WType_TopLevel);
- ImageDisplay* display = new ImageDisplay();
- display->setCaption ( title.c_str() );
- display->setImage ( image, copy );
- display->show();
- return display;
- }
- ImageDisplay* displayImageOverlay ( const NICE::Image* image,
- const NICE::Image *overlay,
- const std::string& title,
- const bool copy )
- {
- if ( ( image->width() != overlay->width() ) ||
- ( image->height() != overlay->height() ) )
- {
- fthrow ( Exception, "Image and overlay image must have the same dimensions." );
- }
- // make sure Qt is initialized
- if ( qApp == NULL ) {
- QtFramework::instance();
- }
- ImageDisplay *display = new ImageDisplay();
- display->setCaption ( title.c_str() );
- display->setImage ( image, copy );
- display->setOverlayImage ( overlay );
- display->show();
- return display;
- }
- ImageDisplay* displayImageOverlay ( const NICE::ColorImage* image,
- const NICE::Image *overlay,
- const std::string& title,
- const bool copy )
- {
- if ( ( image->width() != overlay->width() ) ||
- ( image->height() != overlay->height() ) )
- {
- fthrow ( Exception, "Image and overlay image must have the same dimensions." );
- }
- // make sure Qt is initialized
- if ( qApp == NULL ) {
- QtFramework::instance();
- }
- ImageDisplay *display = new ImageDisplay();
- display->setCaption ( title.c_str() );
- display->setImage ( image, copy );
- display->setOverlayImage ( overlay );
- display->show();
- return display;
- }
- void showImage ( const NICE::Image& image,
- const std::string& title,
- const bool copy ) {
- // display image and wait for the user to close
- // the window
- displayImage ( &image, title, copy );
- QtFramework::exec ( false );
- }
- void showImage ( const NICE::ColorImage& image,
- const std::string& title,
- const bool copy ) {
- // display image and wait for the user to close
- // the window
- displayImage ( &image, title, copy );
- QtFramework::exec ( false );
- }
- void showImageOverlay ( const NICE::Image & image,
- const NICE::Image & overlay,
- const std::string& title,
- const bool copy )
- {
- displayImageOverlay ( &image, &overlay, title, copy );
- QtFramework::exec ( false );
- }
- void showImageOverlay ( const NICE::ColorImage & image,
- const NICE::Image & overlay,
- const std::string& title,
- const bool copy )
- {
- displayImageOverlay ( &image, &overlay, title, copy );
- QtFramework::exec ( false );
- }
- int ImageDisplay::addText ( int x, int y, const std::string& text,
- const Color& color ) {
- Text t ( x, y, text, true, color );
- texts.push_back ( t );
- return texts.size() - 1;
- }
- } // namespace
|