第二章:Linux下Qt使用OpenCV(附赠实例,亲测可用)

接上一章安装linux下安装OpenCV,安装完OpenCV之后,我们要如何在Qt上面使用呢?

目录

一、配置环境

二、 OpenCV读取图片

 三、QLable显示图片

四:总结


一、配置环境

        随意新建一个Qt项目工程,修改项目工程.pro文件。

INCLUDEPATH +=  /usr/local/include/opencv4 \
            /usr/local/include/opencv4/opencv2

LIBS += /usr/local/lib/libopencv_calib3d.so \
        /usr/local/lib/libopencv_highgui.so \
        /usr/local/lib/libopencv_core.so    \
        /usr/local/lib/libopencv_dnn.so    \
        /usr/local/lib/libopencv_features2d.so \
        /usr/local/lib/libopencv_flann.so \
        /usr/local/lib/libopencv_ml.so \
        /usr/local/lib/libopencv_imgproc.so \
        /usr/local/lib/libopencv_imgcodecs.so \
        /usr/local/lib/libopencv_objdetect.so \
        /usr/local/lib/libopencv_video.so \
        /usr/local/lib/libopencv_videoio.so \
        /usr/local/lib/libopencv_stitching.so \
        /usr/local/lib/libopencv_gapi.so \
        /usr/local/lib/libopencv_photo.so

        由于我们安装编译opencv的时候没有指定文件夹,所以默认安装到了/usr/local下,读者根据自身修改.实在不知道这些库在哪里,可以通过find -name 指令查找。

        在main.cpp添加OpenCV头文件,如果没有报错,那说明环境配置没问题。

#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

二、 OpenCV读取图片

        跟上一章一样,在main里面添加如下代码,把图片放到Qt最终可执行程序目录下。

#include "mainwindow.h"
#include <QApplication>
#include <opencv4/opencv2/core/core.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/opencv.hpp>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    cv::Mat img = cv::imread("1.jpg",1);
    if(!img.data)
    {
        printf("No image data\n");
        return -1;
    }
    cv::imshow("window",img);
    cv::waitKey(0);
    return a.exec();
}

        qmake -> 编译 -> 执行,运行成功后显示:

4e7154924870492cac09b30dfafb16aa.png

        程序源码 下载地址

 三、QLable显示图片

        上面的例子是通过cv窗口显示图片,正常项目情况下自然不会这么简单,我们需要通过OpenCV处理完图片后在扔给Qt显示。Qt一般加载图片使用的是QLable,而QLable是通过加载QImage类完成显示。所以我们只需要把Mat的数据给QImage,就可以实现用QLable显示图片了。

        先随意创建一个Qt的窗口,拖两个QLable,一个显示用QImage直接加载图片的样式,一个显示用OpenCV加载再转QImage的样式。

e2665f1013484f78ad69d1ec95a69685.png        左侧使用QImage直接加载图片显示。

QImage srcimg("1.png");
ui->label_src->setPixmap(QPixmap::fromImage(srcimg));
ui->label_src->resize(srcimg.size());

        右侧我们通过OpenCV读取返回Mat,把Mat数据存在QImage,在用lable显示。

void MainWindow::displayImg(cv::Mat mat,QLabel *lable)
{
    cv::Mat rgb;
    QImage temp;
    if(mat.channels() == 3) // RGB image
    {
        //色彩空间转换 opecv默认BGR顺序,QImage是RGB格式
        cv::cvtColor(mat,rgb,CV_BGR2RGB);
        temp = QImage(rgb.data,rgb.cols,rgb.rows,
                             rgb.step,
                             QImage::Format_RGB888);
    }
    else
    {
        temp = QImage((const unsigned char*)mat.data,mat.cols,mat.rows,
                             mat.cols*mat.channels(),
                             QImage::Format_RGB888);
    }

    lable->setPixmap(QPixmap::fromImage(temp));
    lable->resize(temp.size());
}

        运行后结果:

        467f11a028ea41268f22d21a97b75ab7.png

 源码实例

四:总结

        在实例中,值得注意两点。

        第一点:使用了cvtColor做了一次色彩空间转换。那是因为OpenCV默认是BGR格式,而QImage默认的是RGB格式,所以需要有此操作,否则会发现颜色不一样。

       第二点:使用QImage的构造函数的入参,data数据流,width和heigh对应cv的cols和rows,这些常规比较好理解。比较不好理解的是bytesPerLine这个参数,通过QImage的帮助文档,可以知道它标识每行(stride)的字节数,而Mat.Step表示矩阵第一行元素的字节数,所以与它对应,它还可以表示为cols(列数)乘以channels(矩阵中表示一个元素所需要的值的个数,常见一张彩色图片有RGB三个通道)。

ca3d50bd0746412a9ce3fe2f6f022e4c.png

猜你喜欢

转载自blog.csdn.net/u014491932/article/details/125166261