VS2015+Qt+OpenCV+open62541开发过程(07_VS2015+Qt+OpenCV+OPC UA编程)

该文介绍了如何在VS2015中配置OpenCV、OPCUA和Qt的编程环境,并通过Qt设计用户界面,实现从海康威视工业相机读取图像,根据PLC变量值进行图像处理和显示。同时,通过OPCUA读取PLC变量,根据变量值决定是从摄像头采图还是从硬盘读图。在遇到问题时,如图像通道顺序、变量类型转换等,进行了相应的处理和转换。
摘要由CSDN通过智能技术生成

前面几个章节完成了opencv、OPCUA、Qt在VS2015中的编程环境配置及测试,下面进行这几个工具的联合编程,最终实现一个可执行的用户程序,应用场景是利用工业相机采图进行图像处理,具备以下功能:

  1. 读写现场PLC变量功能
  2. 根据PLC变量值从海康威视工业相机采图
  3. 利用opencv对图像进行处理,并与PLC进行通讯交互
  4. 用户界面可以显示当前处理的图像

按照之前章节的步骤,首先测试Qt程序框架中opencv是否可用。

双击项目Form files中的.ui文件,打开Qt designer设计窗口

在左侧控件库中托一个graphview控件到中间的窗口上,这个控件可以作为图片显示的容器。

再添加一个pushbutton按钮,用于触发执行程序,需要添加槽函数start。在.h文件中添加槽函数声明,在.cpp文件中添加槽函数实现。后续的采图通讯、图像处理、界面显示都是在槽函数中实现。

Qt添加的控件对应的头文件也需要添加到代码中,如用到了graphicView控件显示图片,就需要添加#include<QGraphicsView> 头文件,否则读取不到控件名称。

添加控件后在VS中右键项目点重新扫描解决方案,否则添加的控件类在代码中找不到(个人理解就是添加控件后应用一下,控件才会添加到VS中的UI头文件中)

添加pushbutton控件与槽函数的关联,功能是运行程序时,点击开始按钮,触发clicked事件调用槽函数on_start_clicked()执行其中的代码

槽函数实现及解读:

void Qt_test01::on_start_clicked()

{  

    QGraphicsScene *scene = new QGraphicsScene;  //定义显示场景控件,用于将图片显示到主窗口,场景控件作为容器,用于向图片控件传递图片,场景控件在后台中,不会显示到用户界面

    img = cv::imread("..\\pic_test.jpg");   //从硬盘读入一张图片                                           

    h_imgorg = (int)ui.graphicsView->height() - 5;  //设置图片尺寸,比UI界面的图片容器小一点

    w_imgorg = (int)ui.graphicsView->width() - 5;

    cv::resize(img, img, Size(w_imgorg, h_imgorg));  //更改图片尺寸,以适应图片显示控件大小

    Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_RGB888); //Mat格式图像转化为Qt格式图像

    scene->clear();  //场景空间及label空间显示图片或文字前先清空,否则一直覆盖导致内存占用越来越多

    scene->addPixmap(QPixmap::fromImage(Qimg_org)); //场景控件添加图片

    ui.graphicsView->setScene(scene);  //场景控件容器中的图片添加到图片控件

    ui.graphicsView->show();  //图片控件显示图片

   

}

按Ctrl+F5调试,点击开始按钮,可以显示图片,说明opencv没问题,可以使用

继续实验,读取海康威视工业相机,采图并将图片显示到用户窗口中,将读取摄像头代码添加到on_start_clicked()槽函数中。

void Qt_test01::on_start_clicked()

{

    capture = VideoCapture(0); //打开摄像头

    capture.set(CAP_PROP_FRAME_WIDTH, 2448);  // 设置图像宽度

    capture.set(CAP_PROP_FRAME_HEIGHT, 2048);  // 设置图像高度

    capture.set(CAP_PROP_FPS, 5);  // 设置帧率

    if (!capture.isOpened())

    {

        QMessageBox::information(this, "information", "Open camera failed!");

        capture.release();

        return ;

    }

    capture >> img;  //读取视频流中的一帧,写入img 

    QGraphicsScene *scene = new QGraphicsScene;  //定义显示场景控件,用于将图片显示到主窗口,场景控件作为容器,用于向图片控件传递图片,场景控件在后台中,不会显示到用户界面

    //img = cv::imread("..\\pic_test.jpg");   //从硬盘读入一张图片                                          

    h_imgorg = (int)ui.graphicsView->height() - 5;  //设置图片尺寸,比UI界面的图片容器小一点

    w_imgorg = (int)ui.graphicsView->width() - 5;

    cv::resize(img, img, Size(w_imgorg, h_imgorg));  //更改图片尺寸,以适应图片显示控件大小

    Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_BGR888); //Mat格式图像转化为Qt格式图像

    scene->clear();  //场景空间及label空间显示图片或文字前先清空,否则一直覆盖导致内存占用越来越多

    scene->addPixmap(QPixmap::fromImage(Qimg_org)); //场景控件添加图片

    ui.graphicsView->setScene(scene);  //场景控件容器中的图片添加到图片控件

    ui.graphicsView->show();  //图片控件显示图片   

}

按Ctrl+F5调试运行,点击开始按钮,graphicView控件显示相机当前图片成功

继续测试OPC UA读取PLC变量,并根据变量值变化进行采图,这里用之前实验的“test.test.OPC_test”点,等于1时采图并显示,等于0时从硬盘读取图片并显示。再添加两个label控件,实时显示读取的OPC_test数值。

程序添加do循环,循环读取OPC变量值;需要添加closeevent槽函数,当点击关闭应用程序时退出do循环并释放OPC接口和释放相机,否则do循环无法退出程序进入死循环。

两个槽函数修改如下:

void Qt_test01::on_start_clicked()

{

    QGraphicsScene *scene = new QGraphicsScene;  //定义显示场景控件,用于将图片显示到主窗口,场景控件作为容器,用于向图片控件传递图片,场景控件在后台中,不会显示到用户界面

    client = UA_Client_new();  //创建opcua客户端

    UA_ClientConfig_setDefault(UA_Client_getConfig(client));  //设置客户端为默认配置

    status = UA_Client_connect(client, "opc.tcp://127.0.0.1:49320");  //连接服务器,此处连接KEPServer,URL可以通过任务栏KEPServer软件右键,“OPC UA配置”查看

                                                                         //判断opcua客户端连接状态

    if (status != UA_STATUSCODE_GOOD)

    {

        QMessageBox::information(this, "information", "Connect OPC UA Sever Failed");

        return;

    }

    else

    {      

        QMessageBox::information(this, "information", "Connect OPC UA Sever Successful");

    }

    UA_Variant value;  //opcua变量类型

    UA_Variant_init(&value);  //初始化,注意初始化后不能直接读取value.data的值,会导致内存指向错误,必须通过opcua读值或赋值后才能读取value.data   

    capture = VideoCapture(0); //打开摄像头

    capture.set(CAP_PROP_FRAME_WIDTH, 2448);  // 设置图像宽度

    capture.set(CAP_PROP_FRAME_HEIGHT, 2048);  // 设置图像高度

    capture.set(CAP_PROP_FPS, 5);  // 设置帧率

    if (!capture.isOpened())

    {

        QMessageBox::information(this, "information", "Open camera failed!");

        capture.release();

        return ;

    }

    do

    {

        status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(2, "test.test.OPC_test"), &value);

        if (status != UA_STATUSCODE_GOOD)

        {

             QMessageBox::information(this, "information", "OPC UA read Failed");

             return;

        }      

        OPC_test = *(UA_UInt32*)value.data;

        if (OPC_test == 1)

        {

             capture >> img;  //读取视频流中的一帧,写入img 

             h_imgorg = (int)ui.graphicsView->height() - 5;  //设置图片尺寸,比UI界面的图片容器小一点

             w_imgorg = (int)ui.graphicsView->width() - 5;

             cv::resize(img, img, Size(w_imgorg, h_imgorg));  //更改图片尺寸,以适应图片显示控件大小

             Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_BGR888); //Mat格式图像转化为Qt格式图像

             scene->clear();  //场景空间及label空间显示图片或文字前先清空,否则一直覆盖导致内存占用越来越多

             scene->addPixmap(QPixmap::fromImage(Qimg_org)); //场景控件添加图片

             ui.graphicsView->setScene(scene);  //场景控件容器中的图片添加到图片控件

             ui.graphicsView->show();  //图片控件显示图片

        }

        else if(OPC_test == 0)

        {

             img = cv::imread("..\\pic_test.jpg");   //从硬盘读入一张图片                                           

             h_imgorg = (int)ui.graphicsView->height() - 5;  //设置图片尺寸,比UI界面的图片容器小一点

             w_imgorg = (int)ui.graphicsView->width() - 5;

             cv::resize(img, img, Size(w_imgorg, h_imgorg));  //更改图片尺寸,以适应图片显示控件大小

             Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_BGR888); //Mat格式图像转化为Qt格式图像

             scene->clear();  //场景空间及label空间显示图片或文字前先清空,否则一直覆盖导致内存占用越来越多

             scene->addPixmap(QPixmap::fromImage(Qimg_org)); //场景控件添加图片

             ui.graphicsView->setScene(scene);  //场景控件容器中的图片添加到图片控件

             ui.graphicsView->show();  //图片控件显示图片

        }

        ui.label_2->setText(QString::number(OPC_test));

        cv::waitKey(100);  //waitKey()等待时间,opencv显示图片必须加此函数,否则显示不出来

    } while (Flag);      

    UA_Client_delete(client);  //释放opcua client

    capture.release();  //释放摄像头

    return;

}

void Qt_test01::closeEvent(QCloseEvent * event)

{

    Flag = 0;

}

按Ctrl+F5调试

点击开始(OPC_test初始值为0,显示从硬盘读取的图片)

利用Kepsever自带的OPC Quick Client工具修改OPC_test值为1。此时用户界面图片自动显示相机当前图片,并且当前相机图像是实时的动态视频。

总结:

  1. Qt框架开发windows应用程序可以前端图形化开发用户界面,后台编写槽函数,实验中是事件触发型模式,即点击按钮后执行对应的槽函数
  2. 实验中验证了通过OPC UA读写PLC变量(这里用Kepsever的模拟通道,没有直接连接实际的PLC);这里同时也验证了之前文章实验中提到的用open62541 (用到ws2_3lib)验证OPC UA读写时只能在32位(x86)平台下,切换到64位时会报错的问题。利用Qt框架选择64位平台也可以进行OPC UA读写,因为Qt是跨平台的
  3. 实验中用到了Kepsever软件做服务器,需要购买授权,实验中使用试用版有时间限制
  4. Opencv和open62541库是开源免费的
  5. Qt后续开发可用的友好的界面需要继续学习,如界面布局,菜单栏,工具栏,状态栏等功能
  6. 后续利用opencv库对相机采图进行图像处理及算法,需要对opencv进行深入学习
  7. 特别注意各种变量类型转换,如opencv图像为Mat类型,用Qt界面显示需要转换为QImage类型;OPCUA数据为UA_Variant类型,C++数据为long类型,赋值时需要转化
  8. 特别注意图像通道顺序,opencv默认BGR格式,海康相机输出格式可以通过MVS软件进行选择设置,利用海康SDK开发时需要转化格式,利用opencv的VideoCapture则不需要转化格式
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: win10+vs2017+qt+opencv 是一种常用的开发环境组合,可以用于开发图像处理、计算机视觉等应用程序。其中,win10 是操作系统,vs2017 是集成开发环境,qt 是跨平台应用程序开发框架,opencv计算机视觉库。这种组合可以提高开发效率,简化开发流程,同时也具有良好的兼容性和稳定性。 ### 回答2: Win10 vs2017 Qt OpenCV,其实是三个不同的对象,下面将它们逐一进行分析。 Win10,顾名思义,就是Windows 10操作系统的缩写。Windows是全球最为知名的操作系统之一,其在操作界面、软件支持、硬件厂商等方面具有较为广泛的应用和覆盖。Win10更是在基础操作系统的基础上,对界面、安全性、易用性、兼容性等方面进行了优化和改善,使其成为一个更为齐全且更易于使用的操作系统,目前得到了广泛的用户认可。 Vs2017,是Visual Studio的缩写,2017表示该版本发布的年份。Vs是由美国微软公司开发的一款用于软件开发的集成开发环境。Vs不仅包含了代码编写、调试、编译等方面的工具,还提供了一系列辅助开发技术,例如代码重构、版本管理、跨平台开发等等。Vs被广泛应用于Windows平台下的开发,除此之外也支持其他操作系统、开发语言以及开发模式等等,其本身也在持续地更新升级以适应日益变化的开发环境。 Qt,是一个跨平台的C++应用程序开发框架,也被称为“跨平台图形用户界面应用程序开发框架”。Qt是由挪威Trolltech公司于1991年开始开发的,旨在为开发人员提供高效的框架,并能够快速构建新的应用程序。Qt具有良好的可扩展性并提供丰富的开发API,使得其可以被用于开发桌面应用、移动应用、嵌入式应用等等。在跨平台方面,Qt提供了大量的平台支持,例如Windows、Linux、macOS、Android、iOS等等,极大地方便了开发人员的工作。 OpenCV,全称是“开源计算机视觉库”,是一套基于BSD许可协议的跨平台计算机视觉应用程序开发库,可用于开发实时的计算机视觉应用程序。该库广泛应用于学术研究、科研领域以及商业领域,其支持的领域也很广泛,例如目标检测、图像处理、运动跟踪、机器学习等等。OpenCV支持众多编程语言,例如C++、Python、Java等等,也可以被用于多种操作系统上,例如Windows、Linux、macOS等等。 从以上几个对象的简介来看,Win10、Vs2017、QtOpenCV分别是一款操作系统、一个开发工具、一个应用框架和一个开发库。它们是在不同的层面上为开发者和用户提供更好的工具和服务,目的是为了更好地完成软件开发的工作。不过在这些工具之间使用并不是互相排斥的,有时候我们也需要使用它们的组合,以便于完成某些特定的开发任务。 ### 回答3: Win10 VS2017 QT OpenCV是现今非常热门的开发环境,被广泛用于开发图形图像领域。 Win10是目前Microsoft推出的最新的操作系统,与之前的操作系统相比,更加注重用户体验,同时也更注重安全性和稳定性。Win10的更新速度很快,对开发环境与软件的兼容性比之前的版本都要更好。 VS2017是Microsoft推出的最新的开发IDE,它更加注重与异构工具链、云开发的集成,提高了团队合作的效率,同时提供了许多新的代码分析和调试工具,能够更准确地定位出现的错误。此外,VS2017也提供了用于跨平台开发的工具,非常适用于在Win10系统上进行开发QT是一个跨平台的C++开发框架, 其提供了丰富的GUI类库和工具。QT的特点是:跨平台,简单易用,一致性强,可定制化程度高。QT是一款免费的开源软件,因此十分受欢迎。在Win10系统上使用QT进行开发,可以帮助开发者快速地编写GUI应用程序。 OpenCV是一款流行的计算机视觉库,它提供了许多图像和视频处理的函数和算法。OpenCV可用于各大平台的开发,操作方便而深受开发者的青睐。OpenCV适用于Win10系统上,可以在QT环境中使用,为开发者提供优雅高效的图像处理解决方案。 综上所述,在Win10系统中,使用VS2017作为开发IDE,配合QT进行GUI界面的实现与OpenCV进行计算机视觉处理,能够快速地搭建起强大的开发环境。Win10 VS2017 QT OpenCV的组合能够提高开发者的效率与开发程序的稳定性,并应用于图形图像领域的快速开发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值