diff --git a/CMakeLists.txt b/CMakeLists.txt index 5127460a1f..50e1bbdd8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -504,14 +504,7 @@ if (QT4_FOUND AND AUTOSWITCH_QT) set(WITH_QT ON CACHE BOOL "Build with QT Backend support") find_package (OpenGL QUIET) if (QT_QTOPENGL_FOUND AND OPENGL_FOUND) - - #GLU is not mandatory but we used gluPerspective in setGL so, we need it for now. - if (OPENGL_GLU_FOUND) set(WITH_QT_OPENGL ON CACHE BOOL "Add OpenGL extention to QT") - else() - message(STATUS "OpenGL found but not GLU, please install it") - endif() - endif() endif() @@ -535,7 +528,7 @@ if (WITH_QT) endif() if (WITH_QT_OPENGL) - message(STATUS "OpenGL for QT enable (with GLU)") + message(STATUS "OpenGL for QT enable") set(HAVE_QT_OPENGL 1) add_definitions(-DOPENCV_GL=1) endif() diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index 8e4f62b748..613883c0d6 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -70,11 +70,8 @@ endforeach() if(WIN32) if (HAVE_QT) - - #SET(QT_USE_QTXML 1) if (HAVE_QT_OPENGL) set( QT_USE_QTOPENGL TRUE ) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} ${OPENGL_LIBRARIES}) endif() INCLUDE(${QT_USE_FILE}) @@ -97,11 +94,9 @@ endif() if(UNIX) if (HAVE_QT) - - #SET(QT_USE_QTXML 1) if (HAVE_QT_OPENGL) set( QT_USE_QTOPENGL TRUE ) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} ${OPENGL_LIBRARIES}) + #set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} ${OPENGL_LIBRARIES}) endif() INCLUDE(${QT_USE_FILE}) @@ -194,11 +189,8 @@ if(APPLE) endif() if (HAVE_QT) - - #SET(QT_USE_QTXML 1) if (HAVE_QT_OPENGL) set( QT_USE_QTOPENGL TRUE ) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} ${OPENGL_LIBRARIES}) endif() INCLUDE(${QT_USE_FILE}) diff --git a/modules/highgui/include/opencv2/highgui/highgui_c.h b/modules/highgui/include/opencv2/highgui/highgui_c.h index 08be5d83e4..9bf6cada6c 100644 --- a/modules/highgui/include/opencv2/highgui/highgui_c.h +++ b/modules/highgui/include/opencv2/highgui/highgui_c.h @@ -80,8 +80,11 @@ enum { CV_WND_PROP_FULLSCREEN = 0, CV_WND_PROP_AUTOSIZE = 1, + CV_WND_PROP_ASPECTRATIO= 2, CV_WINDOW_NORMAL = 0, - CV_WINDOW_FULLSCREEN = 1 + CV_WINDOW_FULLSCREEN = 1, + CV_WINDOW_FREERATIO = 0, + CV_WINDOW_KEEPRATIO = 1 }; diff --git a/modules/highgui/src/precomp.hpp b/modules/highgui/src/precomp.hpp index 27986c6498..2f1da1149b 100644 --- a/modules/highgui/src/precomp.hpp +++ b/modules/highgui/src/precomp.hpp @@ -177,6 +177,8 @@ double cvGetModeWindow_QT(const char* name); void cvSetModeWindow_QT(const char* name, double prop_value); double cvGetPropWindow_QT(const char* name); void cvSetPropWindow_QT(const char* name,double prop_value); +double cvGetRatioWindow_QT(const char* name); +void cvSetRatioWindow_QT(const char* name,double prop_value); #endif /*namespace cv diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index 8f1d7deddf..3ad87418cc 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -48,7 +48,7 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu switch(prop_id) { //change between fullscreen or not. - case CV_WND_PROP_FULLSCREEN://accept CV_WINDOW_NORMAL or CV_WINDOW_FULLSCREEN + case CV_WND_PROP_FULLSCREEN: if (!name || (prop_value!=CV_WINDOW_NORMAL && prop_value!=CV_WINDOW_FULLSCREEN))//bad argument break; @@ -70,6 +70,12 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu #endif break; + case CV_WND_PROP_ASPECTRATIO: + #if defined (HAVE_QT) + cvSetRatioWindow_QT(name,prop_value); + #endif + break; + default:; } } @@ -106,6 +112,14 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) #else return -1; #endif + + case CV_WND_PROP_ASPECTRATIO: + #if defined (HAVE_QT) + return cvGetRatioWindow_QT(name); + #else + return -1; + #endif + break; default: return -1; diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index 56f2d41ebe..74211deb14 100755 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -53,6 +53,26 @@ QWaitCondition key_pressed; QMutex mutexKey; //end static and global +double cvGetRatioWindow_QT(const char* name) +{ + double result = -1; + QMetaObject::invokeMethod(&guiMainThread, + "getRatioWindow", + //Qt::DirectConnection, + Qt::AutoConnection, + Q_RETURN_ARG(double, result), + Q_ARG(QString, QString(name))); + return result; +} + +void cvSetRatioWindow_QT(const char* name,double prop_value) +{ + QMetaObject::invokeMethod(&guiMainThread, + "setRatioWindow", + Qt::AutoConnection, + Q_ARG(QString, QString(name)), + Q_ARG(double, prop_value)); +} double cvGetPropWindow_QT(const char* name) { @@ -444,6 +464,35 @@ GuiReceiver::GuiReceiver() : _bTimeOut(false) qApp->setQuitOnLastWindowClosed ( false );//maybe the user would like to access this setting } +double GuiReceiver::getRatioWindow(QString name) +{ + QPointer w = icvFindWindowByName( name.toLatin1().data() ); + + + if (!w) + return -1; + + return (double)w->getView()->getRatio(); +} + +void GuiReceiver::setRatioWindow(QString name, double arg2 ) +{ + QPointer w = icvFindWindowByName( name.toLatin1().data() ); + + if (!w) + return; + + int flags = (int) arg2; + + if (w->getView()->getRatio() == flags)//nothing to do + return; + + //if valid flags + if (flags == CV_WINDOW_FREERATIO || flags == CV_WINDOW_KEEPRATIO) + w->getView()->setRatio(flags); + +} + double GuiReceiver::getPropWindow(QString name) { QPointer w = icvFindWindowByName( name.toLatin1().data() ); @@ -741,21 +790,6 @@ CvTrackbar::~CvTrackbar() delete label; } -CustomLayout::CustomLayout() -{ - -} - -int CustomLayout::heightForWidth ( int w ) const -{ - return w/2; - -} -bool CustomLayout::hasHeightForWidth () const -{ - return true; -} - CvWindow::CvWindow(QString arg, int arg2) { moveToThread(qApp->instance()->thread()); @@ -770,7 +804,7 @@ CvWindow::CvWindow(QString arg, int arg2) resize(400,300); //CV_MODE_NORMAL or CV_MODE_OPENGL - myview = new ViewPort(this, CV_MODE_NORMAL,false);//parent, mode_display, keep_aspect_ratio + myview = new ViewPort(this, CV_MODE_NORMAL,CV_WINDOW_KEEPRATIO);//parent, mode_display, keep_aspect_ratio myview->setAlignment(Qt::AlignHCenter); @@ -817,6 +851,8 @@ CvWindow::CvWindow(QString arg, int arg2) show(); } + + CvWindow::~CvWindow() { QLayoutItem *child; @@ -842,6 +878,11 @@ CvWindow::~CvWindow() delete shortcutDown; } +ViewPort* CvWindow::getView() +{ + return myview; +} + void CvWindow::displayInfo(QString text,int delayms) { myview->startDisplayInfo(text, delayms); @@ -920,20 +961,14 @@ void CvWindow::writeSettings()//not tested } //Here is ViewPort -ViewPort::ViewPort(CvWindow* arg, int arg2, bool arg3) +ViewPort::ViewPort(CvWindow* arg, int arg2, int arg3) { centralWidget = arg, mode = arg2; keepRatio = arg3; - modeRatio = Qt::IgnoreAspectRatio; - if (keepRatio) - modeRatio = Qt::KeepAspectRatio; - setupViewport(centralWidget); setContentsMargins(0,0,0,0); - //this->setFrameStyle(0); - //this->setFrameShape(QFrame::Box); setObjectName(QString::fromUtf8("graphicsView")); timerDisplay = new QTimer(this); @@ -943,7 +978,6 @@ ViewPort::ViewPort(CvWindow* arg, int arg2, bool arg3) positionGrabbing = QPointF(0,0); positionCorners = QRect(0,0,size().width(),size().height()); on_mouse = NULL; - deltaOffset = QPoint(0,0); mouseCoordinate = QPoint(-1,-1); @@ -970,6 +1004,18 @@ ViewPort::~ViewPort() delete timerDisplay; } +void ViewPort::setRatio(int flags) +{ + keepRatio = flags; + updateGeometry(); + viewport()->update(); +} + +int ViewPort::getRatio() +{ + return keepRatio; +} + void ViewPort::resetZoom() { matrixWorld.reset(); @@ -1050,9 +1096,6 @@ void ViewPort::updateImage(void* arr) ratioX=float(image2Draw_ipl->width)/float(width()); ratioY=float(image2Draw_ipl->height)/float(height()); - if (keepRatio) - deltaOffset = computeOffset(); - updateGeometry(); } @@ -1067,16 +1110,6 @@ void ViewPort::setMouseCallBack(CvMouseCallback m, void* param) on_mouse_param = param; } -int ViewPort::heightForWidth(int w) const -{ - return w*float(image2Draw_ipl->height)/float(image2Draw_ipl->width); -} - -bool ViewPort::hasHeightForWidth() const -{ - return true; -} - void ViewPort::controlImagePosition() { qreal left, top, right, bottom; @@ -1278,8 +1311,8 @@ void ViewPort::icvmouseProcessing(QPointF pt, int cv_event, int flags) //to convert mouse coordinate qreal pfx, pfy; matrixWorld_inv.map(pt.x(),pt.y(),&pfx,&pfy); - mouseCoordinate.rx()=floor((pfx-deltaOffset.x())*ratioX); - mouseCoordinate.ry()=floor((pfy-deltaOffset.y())*ratioY); + mouseCoordinate.rx()=floor(pfx*ratioX); + mouseCoordinate.ry()=floor(pfy*ratioY); if (on_mouse) on_mouse( cv_event, mouseCoordinate.x(),mouseCoordinate.y(), flags, on_mouse_param ); @@ -1296,23 +1329,31 @@ QSize ViewPort::sizeHint() const } } -QPoint ViewPort::computeOffset() -{ - QSizeF t1(image2Draw_ipl->width, image2Draw_ipl->height); - QSizeF t2(width(),height()); - t1.scale(t2.width(), t2.height(), Qt::KeepAspectRatio); - t2 = (t2 - t1)/2.0; - return QPoint(t2.width(),t2.height()); -} - void ViewPort::resizeEvent ( QResizeEvent *event) { + controlImagePosition(); ratioX=float(image2Draw_ipl->width)/float(width()); ratioY=float(image2Draw_ipl->height)/float(height()); - if(keepRatio) - deltaOffset = computeOffset(); + if(keepRatio == CV_WINDOW_KEEPRATIO)//to keep the same aspect ratio + { + QSize newSize = QSize(image2Draw_ipl->width,image2Draw_ipl->height); + newSize.scale(event->size(),Qt::KeepAspectRatio); + + //imageWidth/imageHeight = newWidth/newHeight +/- epsilon + //ratioX = ratioY +/- epsilon + //||ratioX - ratioY|| = epsilon + if (fabs(ratioX - ratioY)*100> ratioX)//avoid infinity loop / epsilon = 1% of ratioX + { + resize(newSize); + + //move to the middle + //newSize get the delta offset to place the picture in the middle of its parent + newSize= (event->size()-newSize)/2; + move(newSize.width(),newSize.height()); + } + } return QGraphicsView::resizeEvent(event); } @@ -1325,8 +1366,9 @@ void ViewPort::paintEvent(QPaintEvent* event) draw2D(&myPainter); + #if defined(OPENCV_GL) - if (mode == CV_MODE_OPENGL) + if (mode == CV_MODE_OPENGL && false)//disable it for now { setGL(this->width(),this->height()); draw3D(); @@ -1362,7 +1404,7 @@ void ViewPort::paintEvent(QPaintEvent* event) void ViewPort::draw2D(QPainter *painter) { image2Draw_qt = QImage((uchar*) image2Draw_ipl->imageData, image2Draw_ipl->width, image2Draw_ipl->height,QImage::Format_RGB888); - painter->drawImage(deltaOffset.x(),deltaOffset.y(),image2Draw_qt.scaled(this->width(),this->height(),modeRatio,Qt::SmoothTransformation)); + painter->drawImage(0,0,image2Draw_qt.scaled(this->width(),this->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); } void ViewPort::drawStatusBar() @@ -1444,12 +1486,28 @@ void ViewPort::initGL() glEnable( GL_DEPTH_TEST ); } +//from http://steinsoft.net/index.php?site=Programming/Code%20Snippets/OpenGL/gluperspective +//do not want to link glu +void ViewPort::icvgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) +{ + GLdouble xmin, xmax, ymin, ymax; + + ymax = zNear * tan(fovy * M_PI / 360.0); + ymin = -ymax; + xmin = ymin * aspect; + xmax = ymax * aspect; + + + glFrustum(xmin, xmax, ymin, ymax, zNear, zFar); +} + + void ViewPort::setGL(int width, int height) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - gluPerspective(45, float(width) / float(height), 0.01, 1000); + icvgluPerspective(45, float(width) / float(height), 0.01, 1000); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); diff --git a/modules/highgui/src/window_QT.h b/modules/highgui/src/window_QT.h index f990d096dd..90eae9a0b1 100644 --- a/modules/highgui/src/window_QT.h +++ b/modules/highgui/src/window_QT.h @@ -107,6 +107,8 @@ public slots: double isFullScreen(QString name); double getPropWindow(QString name); void setPropWindow(QString name, double flags ); + double getRatioWindow(QString name); + void setRatioWindow(QString name, double arg2 ); }; class CvTrackbar : public QHBoxLayout @@ -133,15 +135,6 @@ private: int* dataSlider; }; -class CustomLayout : public QVBoxLayout -{ - Q_OBJECT - public: - CustomLayout(); - int heightForWidth ( int w ) const; - bool hasHeightForWidth () const; -}; - class CvWindow : public QWidget { Q_OBJECT @@ -153,6 +146,7 @@ public: void updateImage(void* arr); void displayInfo(QString text, int delayms ); void displayStatusBar(QString text, int delayms ); + ViewPort* getView(); QString name; int flags; @@ -195,7 +189,7 @@ class ViewPort : public QGraphicsView { Q_OBJECT public: - ViewPort(CvWindow* centralWidget, int mode = CV_MODE_NORMAL, bool keepRatio = true); + ViewPort(CvWindow* centralWidget, int mode = CV_MODE_NORMAL, int keepRatio = CV_WINDOW_KEEPRATIO); ~ViewPort(); void updateImage(void* arr); void startDisplayInfo(QString text, int delayms); @@ -203,6 +197,9 @@ public: IplImage* image2Draw_ipl; QImage image2Draw_qt; + void setRatio(int flags); + int getRatio(); + public slots: //reference: @@ -218,11 +215,8 @@ public slots: void siftWindowOnUp() ; void siftWindowOnDown(); void resizeEvent ( QResizeEvent * ); - int heightForWidth(int w) const; - bool hasHeightForWidth() const; private: - Qt::AspectRatioMode modeRatio; QPoint deltaOffset; QPoint computeOffset(); QPoint mouseCoordinate; @@ -236,7 +230,7 @@ private: void* on_mouse_param; int mode; - bool keepRatio; + int keepRatio; bool isSameSize(IplImage* img1,IplImage* img2); QSize sizeHint() const; @@ -265,14 +259,13 @@ private: void unsetGL(); void initGL(); void setGL(int width, int height); + void icvgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); #endif private slots: void stopDisplayInfo(); }; - - //here css for trackbar /* from http://thesmithfam.org/blog/2010/03/10/fancy-qslider-stylesheet */ static const QString str_Trackbar_css = QString("")