Why Need This?
- If you have a cv::Mat Image, and Qt is your Gui Helper, then How About Showing A cv::Mat Image on YOUR Gui?
- After Showing a cv::Mat Image on your Gui, Why NOT That let User to interact with it?
What We Need.
- A Be-Ready OpenCV Library
- A Already-Can-Use QT Environment
What We're Gonna Do.
- Inheriting A QLabel Class ----> QcvMatImageLabel
- Show the cv::Mat Image Pixel Value and Current Curor location on LineEdits
- Override the Mouse Move, Press, and Release Events
How???
- Header File of QcvMatLabel
|
#ifndef QCVMATLABEL_H
#define QCVMATLABEL_H
#include <QtGui>
#include <cv.h>
#include <highgui.h>
class QcvMatImageLabel : public QLabel
{
Q_OBJECT
public:
QcvMatImageLabel (QWidget *parent = 0) : QLabel(parent),
cursorLocLineEdit( NULL ),
pixelValLineEdit( NULL ),
matImage( NULL )
{
this->setMouseTracking(true);
}
virtual ~QImageLabel( ){
cursorLocLineEdit = NULL;
pixelValLineEdit = NULL;
matImage = NULL;
}
void setCvImage( cv::Mat _cvImage ){ matImage = _cvImage; }
void setCursorLineEdit( QLineEdit *theLineEdit ){ cursorLocLineEdit = theLineEdit; }
void setPixelValLineEdit( QLineEdit *theLineEdit ){ pixelValLineEdit = theLineEdit; }
int getPosX() const{ return pos_x; }
int getPosY() const{ return pos_y; }
protected:
void mouseMoveEvent( QMouseEvent *ev );
void mousePressEvent( QMouseEvent *ev );
void mouseReleaseEvent(QMouseEvent *ev);
static QImage MatToQImage(const cv::Mat& mat);
QLineEdit *cursorLocLineEdit; // show cursor location, i.e. pixel index
QLineEdit *pixelValLineEdit; // show cv::Mat Image Gray/RGB value
cv::Mat matImage; // current cv::Mat image
int pos_x; // current cursor position
int pos_y; // current cursor position
};
#endif // QCVMATLABEL_H
|
this->setMouseTracking(true);
- Source Code of QcvMatLabel
|
#include "qcvmatimagelabel.h"
void QcvMatImageLabel::mouseMoveEvent( QMouseEvent *ev ){
int x = ev->pos( ).x();
int y = ev->pos( ).y();
pos_x = x; pos_y = y;
if( cursorLocLineEdit != NULL && cursorLocLineEdit->isEnabled( ) )
cursorLocLineEdit->setText( QString( "[ %1 , %2 ]" ).arg( x ).arg( y ) );
if( pixelValLineEdit != NULL && pixelValLineEdit->isEnabled( ) && !matImage.empty( ) ){
pixelValLineEdit->setText( QString( "%1" ).arg( matImage.at<uchar>(y,x) ) );
if( matImage.channels() == 3 )
pixelValLineEdit->setText( QString( "%1 %2 %3" ).arg( matImage.at<cv::Vec3b>(y,x)[0] )
.arg( matImage.at<cv::Vec3b>(y,x)[1] )
.arg( matImage.at<cv::Vec3b>(y,x)[2] ));
}
}
void QcvMatImageLabel::mousePressEvent( QMouseEvent *ev ){
int x = ev->pos( ).x();
int y = ev->pos( ).y();
// m_mousePressed = true;
// Do Whatever You Want...
// Maybe draw a circle on this location on cv::Mat image
}
void QcvMatImageLabel::mouseReleaseEvent(QMouseEvent *ev){
// Usually, this shares a member variable "m_mousePressed"
// with mousePressEvent() method.
// If User presses on image then the mousePressEvent( )
// will be called and set m_mousePressed to be true.
// Then this method can use a "if" condition to check
// and do things like this...
/*
if( m_mousePressed == true ){
// Do Whatever You Want...
// ...
m_mousePressed = false;
}
*/
}
QImage QcvMatImageLabel::MatToQImage(const cv::Mat& mat)
{
// check Show OpenCV Image on QLabel( QImage )
}
|
- Creating a Widget On Your Gui
drag a QLabel to your gui
change the width and height to your cv::Mat image has
change the background color( not necessary )
promote QLabel to QcvMatLabel( very important!!! )
If thing successes, the widget type will look like this
- Coding
|
// Declare a cv::Mat image
cv::Mat srcMat = cv::imread( "Source.jpg" );
// setting up the member variables of QcvMatImage goes here.
// ...
// show cv::Mat image on QLabel
theQcvMatImageLabel->setPixmap( QPixmap::fromImage( MatToQImage( srcMat ) ) );
|
More About Mouse Event...
Sometimes, our target may be 3D image data set. Under this case, we can use mouse wheel to change the current slice to show. The most important thing is overriding this method:
protected:
void wheelEvent( QWheelEvent *event );
And the definition may look like this
void QcvMatImageLabel::wheelEvent( QWheelEvent *event ){
int wheelDegree = event->delta();
int sliceOffSet = -( wheelDegree / 120 );
int newSliceNum = current_slice_number + sliceOffSet;
if( newSliceNum < 0 ) newSliceNum = 0;
if( newSliceNum > maximum_slice_number ) newSliceNum = maximum_slice_number;
// Change-showing-slice code goes here...
// ...
}
wheelDegree is the degree of wheel scrolled on this wheel event
sliceOffSet used as a offset to be added on current slice number
About Key Event
Have Fun!