QT5.8+Opencv2.4.13导入图片并显示

这个题目的内容已经有很多博客写过了,但是我这里为纪念自己的第一篇博客,简单写一个在QT5.8下用Opencv的函数进行图像显示操作。如有和别人的雷同,那纯属巧合(也很容易相同,毕竟这个操作很简单);

作者才疏学浅,如有不对,请多指教。

环境:QtCreator 5.8(我没有在VS用QT插件,VS在编码兼容性上更好一下,但是我VS有问题,等重装个系统再去配置)

opencv 版本是2.4.13,是之前师兄拷贝给我的,就没有用新的3.3版本的,不过2.4.13也差不多。前提是你的电脑配置好的Opencv。

本文要做的内容:

1:新建一个Qt工程

2:创建界面,按键导入图片,显示在主界面上,并用户自定义是否缩放。

3:鼠标追踪,追踪鼠标在图像显示区域内的位置,并在UI上显示出来。

Step 1:

Qt主界面新建一个Qt Widget Application,名字随便取,我取的ImageProcess。

QT5.8+Opencv2.4.13导入图片并显示_第1张图片

编译器选择(这个视状况自定):

QT5.8+Opencv2.4.13导入图片并显示_第2张图片

step 2:

UI界面制作成这样的,现在我们只用“打开图片”按钮,其余先暂时忽略,中间显示图片用的控件是Graphic View,也可以用Label,自定,只是需要修改代码而已。

QT5.8+Opencv2.4.13导入图片并显示_第3张图片

step 3:

在pro文件中,先导入opencv2的库,注意,各方配置不同,这里可能不同,如果你的电脑配置好的,不用这样的操作,请忽略这步

INCLUDEPATH += D:\opencv\opencv\build\include
CONFIG(debug, debug|release): {
LIBS += -LD:\opencv\opencv\build\x86\vc12\lib\
-lopencv_core2413d \
-lopencv_imgproc2413d \
-lopencv_highgui2413d \
-lopencv_ml2413d \
-lopencv_video2413d \
-lopencv_features2d2413d \
-lopencv_calib3d2413d \
-lopencv_objdetect2413d \
-lopencv_contrib2413d \
-lopencv_legacy2413d \
-lopencv_flann2413d
} else:CONFIG(release, debug|release): {
LIBS += -LD:\opencv\opencv\build\x86\vc12\lib\
-lopencv_core2413 \
-lopencv_imgproc2413 \
-lopencv_highgui2413 \
-lopencv_ml2413 \
-lopencv_video2413 \
-lopencv_features2d2413 \
-lopencv_calib3d2413 \
-lopencv_objdetect2413 \
-lopencv_contrib2413 \
-lopencv_legacy2413 \
-lopencv_flann2413
}
step 4:

打开图片按钮命名为 OpenImage_Button,然后右键转到Clicked()槽函数,写入如下代码:

此处需要注意,opencv的Mat数据要显示到Qt需要进行转换,我这里是先把转换到QImage图像,再转Qpixmap,Graphicview即可进行显示,相应转换的函数,可以用这篇博客的:

http://blog.csdn.net/liyuanbhu/article/details/46662115,如果是用Label显示的话,则是直接ui.Label.setpixmap(pixmap)的方法即可显示了。

Fileadd.replace("/","\\");
此句是对文件路径的修改,mat和Qimage读取格式不一样,注意,路径不能有中文,否则读取是空的。

int ImageProcess::on_OpenImage_Button_clicked()
{
    QString Fileadd=QFileDialog::getOpenFileName(NULL,"openfile",QDir::currentPath());
    if(Fileadd.isEmpty())
    {
        QMessageBox::information(NULL,"notice","not opened");
        return -1;
    }
    Fileadd.replace("/","\\");
    std::string ImagePath=Fileadd.toStdString();
    LoadImage=cv::imread(ImagePath,1);
    if(!LoadImage.data)
    {
        QMessageBox::information(NULL,"Error","No file loaded or File name error!");
        return -1;
    }
    float Scales;
    if(Ori_ImageHeight>ui->graphicsView->height()||Ori_ImageWidth>ui->graphicsView->width())
    {
        QMessageBox msgBox;
        msgBox.setText("Size Warning");
        msgBox.setInformativeText("This Image is too big ,need to clip it to property size?");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        msgBox.setDefaultButton(QMessageBox::Yes);
        int ret = msgBox.exec();
        // Get the scales according to the size of image
        if(float(Ori_ImageHeight)/float(ui->graphicsView->height())>
                float(Ori_ImageWidth)/float(ui->graphicsView->width()))
        {
            Scales=1/ (float(Ori_ImageHeight)/float(ui->graphicsView->height()));
        }
        else
        {
            Scales=1/ (float(Ori_ImageWidth)/float(ui->graphicsView->width()));
        }
        switch (ret) {
        case QMessageBox::Yes;                      cv::resize(LoadImage,LoadImage,cv::Size(Ori_ImageWidth*Scales,Ori_ImageHeight*Scales),0,0);
            break;
        default:
            break;
        }
    }
    ImagePixmap=QPixmap::fromImage(cvMat2QImage(LoadImage));
    QGraphicsScene *scene = new QGraphicsScene;
    scene->addPixmap(ImagePixmap);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();
    ui->Width_Image_LineEdit->setText(QString::number(LoadImage.cols));
    ui->Height_Image_LineEdit->setText(QString::number(LoadImage.rows));
}
上面代码中,这段,是对输入的图像进行测试,是否尺寸大于了显示的graphicview,如果大于,就计算长宽比例,取大的那个scales,进行缩小,让图像刚好可以显示在graphicview中。

 if(Ori_ImageHeight>ui->graphicsView->height()||Ori_ImageWidth>ui->graphicsView->width())
    {
        QMessageBox msgBox;
        msgBox.setText("Size Warning");
        msgBox.setInformativeText("This Image is too big ,need to clip it to property size?");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        msgBox.setDefaultButton(QMessageBox::Yes);
        int ret = msgBox.exec();
        // Get the scales according to the size of image
        if(float(Ori_ImageHeight)/float(ui->graphicsView->height())>
                float(Ori_ImageWidth)/float(ui->graphicsView->width()))
        {
            Scales=1/ (float(Ori_ImageHeight)/float(ui->graphicsView->height()));
        }
        else
        {
            Scales=1/ (float(Ori_ImageWidth)/float(ui->graphicsView->width()));
        }
        switch (ret) {
        case QMessageBox::Yes;                       cv::resize(LoadImage,LoadImage,cv::Size(Ori_ImageWidth*Scales,Ori_ImageHeight*Scales),0,0);
            break;
        default:
            break;
        }
    }

测试:

读取一个桌面上的图像,该图像尺寸超过graphicview,graphicviews尺寸800*600 效果如图:

QT5.8+Opencv2.4.13导入图片并显示_第4张图片选择“yes”;


QT5.8+Opencv2.4.13导入图片并显示_第5张图片
图像被缩放至中了。

鼠标追踪(用于后续鼠标选中图像或者画图等操作):

在构造函数中加入,激活控件的鼠标追踪:

 ui(new Ui::ImageProcess)
{
    ui->setupUi(this);
    ui->graphicsView->setMouseTracking(true); 
    setMouseTracking(true);
    ImageProcess::centralWidget()->setMouseTracking(true);
}
在头文件中,添加函数头。

void mousePressEvent(QMouseEvent* event);

鼠标按下 函数体:

此处,鼠标的追踪是相对于整个窗口的,我们只需要显示在graphicview中的鼠标位置,需要用直接追踪出的鼠标位置减去graphicview的位置,就得到在graphicview中的鼠标位置,鼠标位置用event下的pos()方法获取。头文件记得include QCursor

void ImageProcess::mousePressEvent(QMouseEvent* event)
{
    if(event->button() == Qt::LeftButton)
    {
        setCursor(QCursor(Qt::ClosedHandCursor));
        QPoint MouseMainPos=event->pos();
        if(MouseMainPos.x()>=ui->graphicsView->x()&&
                MouseMainPos.x()<=ui->graphicsView->x()+ui->graphicsView->width()&&
                MouseMainPos.y()>=ui->graphicsView->y()&&
                MouseMainPos.y()<=ui->graphicsView->y()+ui->graphicsView->height())
        {
            QPoint Mouse_In_Graphic_pos(MouseMainPos.x()-ui->graphicsView->pos().x(),
                                        MouseMainPos.y()-ui->graphicsView->pos().y());
            MousePosUpdate(Mouse_In_Graphic_pos);

        }
    }
}
效果如下,点击的是图中红色方点位置。鼠标位置被追踪显示在了主界面:

QT5.8+Opencv2.4.13导入图片并显示_第6张图片
如此,完成,后续工作等有时间再更博。

附上代码:

代码中有一些函数还没做,先放在这里了的,起作用的暂时是上面写的部分。

头文件:

#ifndef IMAGEPROCESS_H
#define IMAGEPROCESS_H
#include
#include 
#include 
#include 
#include
#include 
#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include 
#include 
#include 
#include 

#include 


namespace Ui {
class ImageProcess;
}

class ImageProcess : public QMainWindow
{
    Q_OBJECT

public:
    explicit ImageProcess(QWidget *parent = 0);
    ~ImageProcess();
    QImage cvMat2QImage(const cv::Mat& mat);
    cv::Mat QImage2cvMat(QImage image);
    void GetOriginalDataOfTheImage();
 protected:
    void mousePressEvent(QMouseEvent* event);

    void mouseMoveEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent* event);
    void MousePosUpdate(QPoint mp);

private slots:
    int on_OpenImage_Button_clicked();
    void on_Exit_Button_clicked();

private:
    Ui::ImageProcess *ui;
    cv::Mat LoadImage;
    QPixmap ImagePixmap;
     int Ori_ImageHeight;
     int Ori_ImageWidth;
     int Ori_ImageDeepth;
     int Ori_ImageChannel;
    int ImageHeight;
    int ImageWidth;
    int ImageChannel;
};

#endif // IMAGEPROCESS_H
cpp:

#include "imageprocess.h"
#include "ui_imageprocess.h"

ImageProcess::ImageProcess(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ImageProcess)
{
    ui->setupUi(this);
    ui->graphicsView->setMouseTracking(true);//when this is open the graphics view widget can traking mouse
    setMouseTracking(true);
    ImageProcess::centralWidget()->setMouseTracking(true);
}

ImageProcess::~ImageProcess()
{
    delete ui;
}

int ImageProcess::on_OpenImage_Button_clicked()
{
    QString Fileadd=QFileDialog::getOpenFileName(NULL,"openfile",QDir::currentPath());
    if(Fileadd.isEmpty())
    {
        QMessageBox::information(NULL,"notice","not opened");
        return -1;
    }
    Fileadd.replace("/","\\");
    std::string ImagePath=Fileadd.toStdString();
    LoadImage=cv::imread(ImagePath,1);
    if(!LoadImage.data)
    {
        QMessageBox::information(NULL,"Error","No file loaded or File name error!");
        return -1;
    }
    float Scales;
    GetOriginalDataOfTheImage();
    if(Ori_ImageHeight>ui->graphicsView->height()||Ori_ImageWidth>ui->graphicsView->width())
    {
        QMessageBox msgBox;
        msgBox.setText("Size Warning");
        msgBox.setInformativeText("This Image is too big ,need to clip it to property size?");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        msgBox.setDefaultButton(QMessageBox::Yes);
        int ret = msgBox.exec();
        // Get the scales according to the size of image
        if(float(Ori_ImageHeight)/float(ui->graphicsView->height())>
                float(Ori_ImageWidth)/float(ui->graphicsView->width()))
        {
            Scales=1/ (float(Ori_ImageHeight)/float(ui->graphicsView->height()));
        }
        else
        {
            Scales=1/ (float(Ori_ImageWidth)/float(ui->graphicsView->width()));
        }

        // cv::Size toSize(ui->graphicsView->width(),ui->graphicsView->height());
        switch (ret) {
        case QMessageBox::Yes:            cv::resize(LoadImage,LoadImage,cv::Size(Ori_ImageWidth*Scales,Ori_ImageHeight*Scales),0,0);
            break;
        default:

            break;
        }
    }
    ImagePixmap=QPixmap::fromImage(cvMat2QImage(LoadImage));
    QGraphicsScene *scene = new QGraphicsScene;
    scene->addPixmap(ImagePixmap);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();
    ui->Width_Image_LineEdit->setText(QString::number(LoadImage.cols));
    ui->Height_Image_LineEdit->setText(QString::number(LoadImage.rows));
}
QImage ImageProcess::cvMat2QImage(const cv::Mat& mat)
{
    if(mat.type() == CV_8UC1)
    {
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        image.setColorCount(256);
        for(int i = 0; i < 256; i++)
        {
            image.setColor(i, qRgb(i, i, i));
        }
        uchar *pSrc = mat.data;
        for(int row = 0; row < mat.rows; row ++)
        {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc += mat.step;
        }
        return image;
    }
    else if(mat.type() == CV_8UC3)
    {    
        const uchar *pSrc = (const uchar*)mat.data;
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    else if(mat.type() == CV_8UC4)
    {
        const uchar *pSrc = (const uchar*)mat.data;
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
        return image.copy();
    }
    else
    {
        qDebug() << "ERROR: Mat could not be converted to QImage.";
        return QImage();
    }
}
cv::Mat ImageProcess:: QImage2cvMat(QImage image)
{
    cv::Mat mat;
    switch(image.format())
    {
    case QImage::Format_ARGB32:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32_Premultiplied:
        mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_RGB888:
        mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        cv::cvtColor(mat, mat, CV_BGR2RGB);
        break;
    case QImage::Format_Indexed8:
        mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
        break;
    default:
        QMessageBox::warning(NULL,"warning","format is not right");
        exit(0);
    }
    return mat;
}
void ImageProcess:: GetOriginalDataOfTheImage()
{
    Ori_ImageHeight=LoadImage.rows;
    Ori_ImageWidth=LoadImage.cols;
    Ori_ImageDeepth=LoadImage.depth();
    Ori_ImageChannel=LoadImage.channels();

}


void ImageProcess::on_Exit_Button_clicked()
{
    QMessageBox msgBox;
    msgBox.setText("The Image has been modified.");
    msgBox.setInformativeText("Do you want to save your changes?");
    msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Save);
    int ret = msgBox.exec();
    exit(0);
    /*  switch (ret) {
        case QMessageBox::Save:
          this->savefileslot();//turn to save slot
            // Save was clicked
            break;
        case QMessageBox::Discard:
          event->accept();
            // Don't Save was clicked
            break;
        case QMessageBox::Cancel:
          event->ignore();
            // Cancel was clicked
            break;
        default:
            // should never be reached
            break;
      }

      } else {
          event->accept();
      }*/
}
void ImageProcess::mousePressEvent(QMouseEvent* event)
{
    if(event->button() == Qt::LeftButton)
    {
        setCursor(QCursor(Qt::ClosedHandCursor));
        QPoint MouseMainPos=event->pos();
        if(MouseMainPos.x()>=ui->graphicsView->x()&&
                MouseMainPos.x()<=ui->graphicsView->x()+ui->graphicsView->width()&&
                MouseMainPos.y()>=ui->graphicsView->y()&&
                MouseMainPos.y()<=ui->graphicsView->y()+ui->graphicsView->height())
        {
            QPoint Mouse_In_Graphic_pos(MouseMainPos.x()-ui->graphicsView->pos().x(),
                                        MouseMainPos.y()-ui->graphicsView->pos().y());

            MousePosUpdate(Mouse_In_Graphic_pos);

        }
    }
}

void ImageProcess::mouseMoveEvent(QMouseEvent *event)
{
   /* QPoint MouseMainPos=event->pos();
    if(MouseMainPos.x()>=ui->graphicsView->x()&&
            MouseMainPos.x()<=ui->graphicsView->x()+ui->graphicsView->width()&&
            MouseMainPos.y()>=ui->graphicsView->y()&&
            MouseMainPos.y()<=ui->graphicsView->y()+ui->graphicsView->height())
    {
        QPoint Mouse_In_Graphic_pos(MouseMainPos.x()-ui->graphicsView->pos().x(),
                                    MouseMainPos.y()-ui->graphicsView->pos().y());

        MousePosUpdate(Mouse_In_Graphic_pos);

    }*/ //这个函数取消注释会一直追踪显示鼠标位置,此处没有设置采样时间,会很卡,如果要启用,请设置时间,不然也显示不好

}

void ImageProcess::mouseReleaseEvent(QMouseEvent *event)
{
    setCursor(QCursor(Qt::ArrowCursor));
}
void ImageProcess::paintEvent(QPaintEvent* event)
{

}
void ImageProcess::MousePosUpdate(QPoint mp)
{
    ui->MousePos_X->setText(QString::number(mp.x()));
    ui->MousePosY->setText(QString::number(mp.y()));
}

第一篇博客,就这样吧。有空继续往下做


你可能感兴趣的:(自己写的博客,图像处理,qt,Opencv)