如何使用QT框架进行海康机器视觉算子SDK二次开发

目录

1.使用QT进行算子SDK二次开发需要了解那些知识?

1.1 了解SDK的安装目录下各个文件的作用。

1.1.1 头文件和静态库

1.1.2 C#需要引用的库

1.1.3 运行时依赖库

1.1.4 帮助文件

1.1.5 环境检测等实用工具

1.2 具备基本的C++编程基础知识

1.3 了解算子SDK在底层做了哪些工作?

1.3.1 算子SDK 简化了算子的初始化流程

1.3.2 算子SDK简化了参数设置和参数获取

1.3.3 算子SDK以面向对象的方式封装了算子工具

2.算子SDK二次开发QT开发环境配置

2.1 使用QtCreator作为集成开发环境

2.2 使用VisualStudio作为集成开发环境

3.典型的算子工具调用流程

4.如何渲染算子工具的运行结果

5.在VisualStudio环境中如何编辑渲染控件的信号和槽


1.使用QT进行算子SDK二次开发需要了解那些知识?

1.1 了解SDK的安装目录下各个文件的作用。

  1. 用户在安装完Vision Master软件之后,默认会在C盘Program Files(x86)目录下安装算子开发包,典型的路径是这样的:

    C:\Program Files (x86)\MVDAlgorithmSDK

    在此目录下,应该会看到以下文件夹

         

下面分别讲一下图中各个文件夹的作用。

1.1.1 头文件和静态库

使用C++语言进行算子SDK二次开发,最为常见的方式是使用静态库.lib加头文件.h的方式,因此Includes和Libraries这两个文件夹是我们所关心的。后面在开发环境配置中会重点介绍着两个文件夹如何引用。

1.1.2 C#需要引用的库

其中ReferencedAssemblies文件夹中用户也可以发现大量的DLL,这些DLL是使用C#语言进行算子二次开发才需要用到的,对于C++开发者来说不需要关心,所以不必关注 。

1.1.3 运行时依赖库

Runtime文件夹非常重要,这是使用算子SDK开发的应用程序运行时需要依赖的动态库,缺少它您开发的应用程序将无法运行,如果您想要在一台没有安装算子SDK软件包的电脑上运行您的二次开发程序,您可以将Runtime文件下的x64文件夹(如果是32位系统,就是win32文件夹)下的所有文件复制到你开发的exe所在目录即可。对于在一台已经安装了算子SDK开发包的电脑上运行您开发的视觉应用程序,则完全不必进行前面所说的操作,因为Runtime的路径已经写到环境变量中,程序运行时依赖的动态库会首先从环境变量中查找。

1.1.4 帮助文件

  Documents文件夹存放的时开发需要查询的开发的帮助文档,这个文档对于视觉应用开发者来说是非常重要的,算子类库的用法和各种内置数据类型可以通过查询文档知道。

Samples文件夹存放的是二次开发示例程序,如果您需要快速入门,可以直接跳到这个文件夹内查看相关的示例程序。

1.1.5 环境检测等实用工具

MVDTools文件夹存放是环境的检测工具之类的应用程序,视觉应用的二次开发不必了解这个。

1.2 具备基本的C++编程基础知识

首先,具备基础的C++编程知识,算子SDK开发需要掌握的C++知识点并不多,并不需要对C++各种知识面面俱到的了解。这里对其中涉及到的一些基础知识点做一些简单介绍,以便在二次开发过程中能很好的理解算子SDK的用法。

在算子SDK中,开发者会经常遇到I开头的类,例如IMvdImage, IMvdShape, IHPFeaturePatMatchTool , 这个IInterface的首字母,所以IMvdImage, IMvdShape等都是抽象类,是不可以直接实例化的,所以类似下面这样的语句是无意义的。

IMvdImage image

你也不可以像下面这样写,编译通不过的:

IMvdImage *pImage = new IMvdImage();

以IMvdImage这个图像类举例来说,正确的用法是这样的:

//读取D盘下的图像文件testImage.bmp
IMvdImage *pImage;
CreateImageInstance(&pImage);
pImage.InitImage(“D:\\testImage.bmp”,MVD_PIXEL_MONO_08);

在算子SDK中绝大多数类都是抽象类,都不能直接实例化,需要显式的调用CreateXXXInstance(XXX指代某个具体类,如Image类),然后才能对其进行操作,否则就会出现空引用,从而引发程序异常。

1.3 了解算子SDK在底层做了哪些工作?

1.3.1 算子SDK 简化了算子的初始化流程

算子SDK的二次开发简化了算子的初始化工作。在算子初始化过程中,需要对算子进行加密校验和解密,然后根据算子的能力集进行内存分配,除此之外,还需要对常用的运行参数设置初始的默认值,这些工作对于视觉应用的开发者来说较为繁琐和重复,因此算子SDK对这些流程都做了封装,开发者只需要一行代码就可以实现算子的初始,大大降低了开发者调用底层机器视觉算法的难度和负担。

1.3.2 算子SDK简化了参数设置和参数获取

算子SDK的二次开发简化了算子的参数设置,算子的运行参数在底层实际上是对应不同的结构体,在开发者不了解这些运行参数的数据类型和结构体的情况下,想要直接设置底层算子的运行参数难度就很大。但算子SDK对这参数设置这部分也做了很好的封装,用户只需要调用算子工具的SetParam函数接口,就可以在不了解底层算子运行参数结构体的情况下,也能将参数设置进去。SetParam函数提供了两个参数,一个参数是paramName, 一个参数是paramValue,开发者只需要查阅帮助文件,找到对应工具的参数表格,就可以设置参数。例如:设置快速模板匹配工具的最小匹配得分:

FastFeatureMatchTool1.SetParam(“MinScore”,”0.65”);

同样,开发者通过GetParam接口也能很方便的获取算子工具的当前参数值。

1.3.3 算子SDK以面向对象的方式封装了算子工具

有过Halcon视觉开发经验的开发者都知道,底层算子的调用灵活性很高,但是完全是面向过程的,不能很好的做到代码的重用,用户需要自己使用C++设计模式去构建自己的算子类库,而我们的算子SDK就是封装好的算子类库,算子实例化之后,通过暴露的接口API设置其属性,调用其方法就能控制算子工具,而不需要程序自己去管理算子工具的内部状态,视觉应用的开发者只需要将更多的精力放在业务逻辑层,而不必关系算子内部是如何工作的。

使用Qt框架开发桌面应用程序,开发者通常有两种选择,一种是在Qt官方提供的集成开发环境QtCreator中进行开发,优势是配置引用相对简单,通过一个pro文件,qmake工具会自动生成makefile, 另外,QtCreator的代码实时纠错提醒以及高度集成的帮助文件系统,开发者遇到不了解的API只需要按下F1就能自动导航到帮助文档对应的条目,这个是很多开发者喜欢QtCreator的原因,但是QtCreator的调试工具做得确实不如VisualStudio, 调试时不如VisualStudio方便,VisualStudio可以很方便的查看但变量的值,而在QtCreator中,对于用户自定义的数据类型,往往只能看到这个变量的指针,而不能查看到具体的变量值。因此有一部分开发者选择VisualStudio作为集成开发环境,下面分别介绍这两种环境下如何配置算子SDK的二次开发。

2.算子SDK二次开发QT开发环境配置

2.1 使用QtCreator作为集成开发环境

创建Qt工程后,在pro文件中,需要添加一些配置,pro文件的典型写法如下截图所示:

如图所示,在pro文件的第1行,QT += core gui axcontainer 表示我们需要用到头文件,特别的axcontainer ,这个是算子SDK开发需要用到ActiveX控件,所以必须要添加axcontianer.

在pro文件的第22行,必须在工程的根目录下放上mvrenderactivexlib.cpp文件,pro文件的第25行,必须在工程的根目录下放上mvrenderactivexlib.h头文件。

在pro文件的第29行,定义了一个宏 MVD_INSTALL_DIR, 将算子包的安装目录指定当前工作目录的往上4级,其实就是C:/Program Files (x86)/MVDAlogrithmSDK 这个路径,由于pro文件中配置的路径不允许存在空格或者中文字符,所以用$quote( )包含起来。

在pro的第31行,指定工程引用到的头文件。这个时候我们前面定义的MVD_INSTALL_DIR就起到作用了,可以缩短头文件路径的写法。

接着我们还需要指定静态库的路径和依赖的动态库路径,如下图所示:

在pro文件的第43行,指定win64工程需要链接的动态库,写法是:

         LIBS += -L$$静态库路径 –l静态库名称

如图所示,MVDShapeCpp.lib和MVDImageCpp.lib 是必须用到的库,无论你用到什么算法工具,这个都是必不可少的,而MVDAlmightyPatMatchCpp.lib, MVDPreproMaskCpp.lib, MVDCircleFindCpp.lib 则是根据工程是否用到来决定是否添加,没有到相关的算子工具,则无需添加。

在pro文件的第52行,指定的是win32工程需要链接的静态库。

至此,pro文件就配置好了,开发者可以参照这个pro文件的写法来配置自己的工程,写法是基本一致的,只需要修改一下MVD_INSTALL_DIR这个宏指代的MVDAlgorithmSDK的安装路径就好了,然后再根据自己的需求,添加需要用到静态库(修改上面pro文件的44-47行,54-56行的内容即可)。

配置完pro文件,接着是添加用到的渲染控件,打开Qt Designer, 在窗口设计器中,把ActiveX控件的容器QAxWidget 拖到窗口中,如下图所示:

                                                             添加QAxWidget容器到窗体中

添加了ActiveX控件的容器后,我们就需要添加具体的ActiveX控件了,在窗体设计器中,对着拖进去的QAxWidget这个容器右键,选择需要加Activ控件,如下图所示:


在弹出右键菜单中选择“设置控件”,然后在弹出的对话框中,输入Mv,会过滤掉很多不需要选择的控件,选择MvRenderActivex Control。

好了,到了这一步,基本上QT的配置就完成,还需要在工程的头文件中添加一些常用的头文件,例如,在mainwindow.h头文件中添加算子SDK二次开发常用的头文件。如下:

                                                                                    添加算子SDK常用头文件

2.2 使用VisualStudio作为集成开发环境

我们以VisualStudio 2017为例,在VS中开发Qt应用程序,就不需要什么pro文件,只需要在工程设置中设置头文件路径和静态库路径。
首先设置附加头文件目录,在VS菜单栏中找到“项目”->“xxx项目属性”(这里xxx指代用户的项目名称)在弹出的对话框中设置附加头文件目录,如下图所示:

                                                                   设置附加包含目录

接着编辑附加包含目录,这些附加的包含目录是必不可少的,必须添加,否则程序编译会报错,分别是

$(QTDIR)\include\ActiveQt;

$(MVDALGO_DEV_ENV)\Includes\Algorithm; $(MVDALGO_DEV_ENV)\Includes\MvRenderOcx;

$(MVDALGO_DEV_ENV)\Includes\VisionDesiner;

添加ActiveQt目录是因为需要用到AcitveX容器,Algorithm, MvRenderOcx, VisionDesigner这几个头文件目录包含了渲染控件,以及所有算子需要用到的 头文件,如下图所示:

                                                                       编辑附加头文件路径

设置完了附加头文件路径,接着就是设置附加静态库路径和链接时需要链接的静态库名称,如下图所示:

                                                                    配置附加静态库路径

编辑附加库目录,如下图所示:

 

                                                               编辑附加库目录 

 切换到链接器的“输入”,设置链接的静态库名称,如下图所示:

                                                               编辑需要链接的静态库名称 

链接的静态库Qt5AxBased.lib,Qt5AxContainerd.lib 是必不可少的(注意这里库名称后面带有d,表明工程配置是Debug生成模式,如果用户工程配置的是Release模式,则不需要带d),因为需要用到ActiveX容器。MVDShapeCpp.lib, MVDImageCpp.lib 也是必不可少的。而MVDCircleFindCpp.lib则需要根据开发者是否用到做取舍,如果没用到则不必添加,如果用到其他的算子工具,必须在这里添加其他算子工具的静态库名称。

3.典型的算子工具调用流程

算子工具的典型调用流程如下:

我们以调用圆查找算子工具为例(例子只是为了解释说明调用流程,不具有实际意义),典型的代码如下:

//创建一个矩形框作为圆查找ROI
IMvdRectangleF *pRect;
CreateRectangleInstance(&pRect,currentImage->GetWidth()/2,currentImage->GetHeight()/2,100,100);
//创建一个圆查找工具实例
ICircleFindTool *pCircleFindTool;
CreateCircleFindToolInstance(&pCircleFindTool);
//设置输入图像
pCircleFindTool->SetInputImage(currentImage);
//设置圆查找ROI
pCircleFindTool->SetROI(pRect);
//运行圆查找工具
pCircleFindTool->Run();
//获取圆查找结果
ICircleFindResult *pResult = pCircleFindTool->GetResult();
if(pResult!=nullptr)
{
      MVD_POINT_F cent = pResult->GetCircleCenter();
      qDebug()<<"CentX="<<cent.fX<<"CentY="<<cent.fY;
}
else
{
      qDebug()<<"CircleFindTool NG";
}

4.如何渲染算子工具的运行结果

算子工具运行完成后,我们可以获取其结果,将结果组装成各种IMvdShape,然后将Shape添加到控件的Shape列表中。添加后渲染控件就会自动渲染图形结果了。我们还是用代码来说明问题。

首先,编写一个函数,用来显示图像和渲染Shape,代码如下:

/**
 * @brief 在控件上显示图像
 * @param pImage 输入图像
 */
void MainWindow::ShowImage(IMvdImage *pImage)
{
    if(pImage!=nullptr)
    {
        long long nInImgPtr = (long long)(currentImage);
        QVariant vInputImg(nInImgPtr);      ui->axWidgetRender->dynamicCall("MV_LoadImageFromObject(const QVariant& varImageObj)", vInputImg);
        ui->axWidgetRender->dynamicCall("MV_Display()");
        pPreproMaskTool->SetInputImage(currentImage);
    }
}

/**
 * @brief 添加图形源
 * @param pShape 输入图形
 */
void MainWindow::AddShape(IMvdShape *pShape)
{
    QVariant qVarHandle(reinterpret_cast<long long>(pShape));
    MVD_SHAPE_HANDLE handle = 0;
    MVD_SHAPE_HANDLE* pHandle = &handle;
    QVariant pQVarHandle((long long)(pHandle));
    ui->axWidgetRender->dynamicCall("MV_AddShapeEx(const QVariant&, const QVariant&)", qVarHandle, pQVarHandle);
}

为了简化清除图形和显示图形的写法,我们再定义两个宏,一个用来清除控件上的所有图形,一个用来刷新控件的显示。

#define CLEAR_SHAPES ui->axWidgetRender->dynamicCall("MV_ClearShapes()")
#define MVD_DISPLAY ui->axWidgetRender->dynamicCall("MV_Display()")

这样我们只需要在需要清除图形的地方添加CLEAR_SHAPES; 需要刷新控件显示的地方添加MVD_DISPLAY。

好了,渲染算子的运行结果功能就完备了,再举一个完整的简单例子来说明渲染控件的用法。

举例:调用圆查找功能算子,并渲染圆查找结果,代码如下:

try 
{
        //清除图形
        CLEAR_SHAPES;
        //显示图像
        ShowImage(currentImage);
        //实例化一个扇环区域,扇环中心100,100,内径40,外径80,起始角//度0,终止角度360
        IMvdAnnularSectorF *pAnnualarsector;       CreateAnnularSectorInstance(&pAnnualarsector,MVD_POINT_F{100,100},40,80,0,360);  
        //实例化圆查找工具
        ICircleFindTool *pcirFindTool;
        CreateCircleFindToolInstance(&pcirFindTool);
        //设置输入图像
        pcirFindTool->SetInputImage(currentImage);
        //设置ROI
        pcirFindTool->SetROI(pAnnualarsector);
        //算子运行
        pcirFindTool->Run();
	    //获取结果
        ICircleFindResult *pCirleFindResult = pcirFindTool->GetResult();
        if(pCirleFindResult!=nullptr)
        {
         //在控件上渲染查找到的圆
        IMvdCircleF *pCircle;
        CreateCircleInstance(&pCircle,MVD_POINT_F{0,0},10);
        pCircle->SetCenter(pCirleFindResult->GetCircleCenter();    
        pCircle->SetRadius(pCirleFindResult->GetCircleRadius();
        pCircle->SetBorderColor(MVD_COLOR{0x7f,0xff,0,0});
        AddShape(pCircle);
        }
        MVD_DISPLAY;        
} 
catch (IMVDException &ex) 
{
       QString errorMessage = QString::fromLocal8Bit("执行算法模块发生异常,返回错误码")+QString::number(ex.GetErrorCode(),16);
       QMessageBox::warning(this,"Warning",errorMessage);
}

5.在VisualStudio环境中如何编辑渲染控件的信号和槽

不同于在QtCreator中,在VS中打开QtDesigner,编辑渲染控件时,渲染控件的右键菜单中并不能找到“转到槽”这一项。这一点确实不如在QtCreator中打开QtDesigner来的方便。但我们还是有办法来达到添加信号和槽的目的。

方法1:手动添加connect函数,例如连接渲染控件图形发生改变信号到槽函数

connect(ui.axWidget,
SIGNAL(MV_SHAPECHANGED(int,int,QVariant&)),
this,
SLOT(OnShapechanged(int,int,QVariant&)));

方法2:按照命名规范添加槽函数

Qt会自动给每一个控件将的信号和槽连接起来,原因是在窗体的构造函数中调用了SetupUi函数,而在SetupUi函数的最后一行有一条语句:

QMetaObject::connectSlotsByName(MainWindow)

如果我们写的槽函数符合on_对象名_信号名,就会自动将信号和槽连接上,例如渲染控件的名称是axWidget,我们在头文件中声明一个槽函数:

on_axWidget_MV_SHAPECHANGED(int eventType,int shapeType,QVariant& shapeHandle)

然后在CPP文件中实现这个函数即可。

举例:获取用户在渲染控件上绘制的ROI对象。

在QtGuiApplication.h文件中声明一个槽函数

void OnShapechanged(int eventType,int shapeType,QVariant& var);

然后声明一个IMvdRectangleF* roi 用来存放ROI数据

如下图所示:

接着在QtGuiApplication.文件中实现上面添加的槽函数

在窗体的构造函数中,连接信号和槽,并创建ROI的实例,如下图所示:

接着我们要实现槽函数onShapeChanged(int,int,QVariant&)

这个函数表达的意思是:只接受当前绘制矩形框作为ROI,用户右键添加的其他图形无视。

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 海康相机SDK海康威视公司推出的一款相机软件开发工具包,它可以帮助开发者实现对海康相机的控制与数据处理。而使用Qt编写的二次开发程序可以在跨平台、界面友好、开发效率高等方面表现出色。因此,将海康相机SDK二次开发Qt的方法可以有效提高开发效率和使用体验。 在二次开发Qt程序之前,首先需要安装海康相机SDKQt开发环境。然后,通过SDK给出的样例程序,了解相机控制和数据处理的基本操作。接下来,结合Qt的开发框架,建立相应界面和事件响应,并利用海康相机SDK提供的函数,实现相机的开启、关闭、捕获图片等操作。同时,也要考虑到QtSDK之间的数据转换和参数传递的问题。 在开发过程中,需要注意一些细节问题,如相机连接状态的检测、相机参数的设置、图像处理算法的优化等。同时,也可以结合其他相关的开源库,如OpenCV等,进一步丰富程序的功能。 总之,海康相机SDK二次开发Qt是一个非常有前景和实际意义的开发方向。通过此类程序的开发,可以提高海康相机的应用范围和应用效果,满足不同用户的实际需求。 ### 回答2: 海康相机SDK是一款网络摄像机开发工具包,可以提供高质量的视频流和图像采集,集成该SDKQT开发环境中可以实现基于网络摄像机的图像处理和视频监测应用的开发。 在使用海康相机SDK进行QT二次开发的过程中,需要首先了解SDK操作和QT编程的基本知识。在使用SDK时,需要通过SDK提供的API进行网络摄像机的控制、图像采集和视频流显示等操作。在此基础上,可以使用QT编程实现各种功能和应用,例如图像增强、文本识别、动态拍照和视频监测等。 在进行二次开发时,还需要注意SDK的版本选择和兼容性问题。另外,需要考虑软硬件平台的匹配问题,例如CPU架构、操作系统和网络接口等。在具体实现中,可以使用QT提供的多种工具和组件,例如QT designer、QT creator和QT widgets等,以提高开发效率和代码质量。 总之,通过海康相机SDK二次开发QT编程的结合,可以实现基于网络摄像机的各种应用和功能,为用户提供更加便捷、高效的视频监测和图像处理体验。 ### 回答3: 海康相机sdk是一个旨在为开发者提供海康威视相机设备的二次开发接口的软件开发工具包。对于开发者来说,使用海康相机sdk进行二次开发是非常重要的,这是因为该工具包提供了丰富的API,可以使开发者更加高效地定制相机设备的软件功能。 在海康相机sdk二次开发中,Qt是一种流行的跨平台开发框架,可以集成到C++中,使用Qt编写对于初学者来说也比较容易上手。我们可以使用Qt Creator IDE来编写程序,该IDE支持快速的窗口设计和多线程开发。同时,Qt还提供了很好的图形用户界面(GUI)支持,这对于开发相机设备用户友好的UI界面非常重要。 在使用海康相机sdk进行二次开发时,我们需要遵守相应的开发流程,首先需要进行硬件设备连接和查询,然后创建相应的海康相机对象,并且设置相机参数、注册回调函数等。之后,我们可以使用Qt编写界面并添加关于设备的一些功能,例如录像、拍照和保存数据等。 总之,使用海康相机sdk进行二次开发是一个涉及不同技术的综合性开发过程,例如设备硬件、图像处理、网络和GUI开发,同时也需要注意程序的健壮性和安全性等方面的考虑。虽然这个过程可能会面临一些挑战,但是在付出努力后,我们可以获得一个高效且功能强大的相机设备软件,满足我们的需求。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值