C++调用HALCON引擎

1.C++项目引用HALCON依赖

1.1C++项目引用HALCON依赖

pro添加

# HALCON
#include
INCLUDEPATH += $$(HALCONROOT)/include
INCLUDEPATH += $$(HALCONROOT)/include/halconcpp
INCLUDEPATH += $$(HALCONROOT)/include/hdevengine
#libs
LIBS += -L$$(HALCONROOT)/lib/$$(HALCONARCH) -lhalcon -lhalconcpp -lhdevenginecp

1.2添加HALCON头文件、命名空间

设置路径

#include "HalconCpp.h"

#include "HDevEngineCpp.h"

using namespace HalconCpp;

using namespace HDevEngineCpp;

2.流程介绍

2.1引擎命名空间

主要用得到的类:HDevEngine、HDevProgram、HDevProgramCall、HDevProcedure、HDevProcedureCall、HDevOpMultiWindowImpl、HDevEngineException。

HDevEngine类是管理全局设置。如设置或获取全局变量的值、设置脚本路径、启动停止调试模式等。

HDevProgram类加载.hdev格式文件以及获取文件内部参数一般信息。

HDevProgramCall类执行.hdev文件格式脚本,并获取变量的值。

HDevProcedure类加载.hdvp格式外部函数以及内部函数。

HDevProcedureCall类执行.hdvp外部函数和内部函数。并且可以设置或获取外部函数、内部函数参数。

HDevOpMultiWindowImpl类主要是与显示结果相关,在脚本中执行的结果可以显示在C#中。

HDevEngineException类是引擎相关的异常类。

本文档以.hdvp为例子

2.1.1准备.hdvp函数

try

   *输入

    Param1:=Param1

    Param2:=Param2

    Param3:=Param3

    Param4:=Param4

    if(Param1='查找模板OK' and Param2='测量成功' and Param3='测量成功' and Param4='测量成功')

            Result:=0

            Result1:='OK'

    else

        Result:=1

        Result1:='NG'

    endif

catch (Exception)

    Result:=-1

    ErrorString:=Exception

endtry

return ()

函数接口如下:5个输入,2个输出。同时添加参数文档说明(包含多种语言,需要设置需要的语言文档)。

2.1.2QT中调用该程序

全局变量

HDevEngine* MyEngine;//引擎

HDevProcedure *Program ;//函数

HDevProcedureCall* ProcCall;//函数回调

首先初始化引擎,需要设置语言和引擎文件的路径,路径设置不正确,找不到外部函数;同时可以获取该目录下的函数

MyEngine = new HDevEngine();

    //设置文档语言,因为使用的中文需要设置,默认英文,语言不对应拿不到参数说明

    MyEngine->SetEngineAttribute("docu_language","zh_CN");

    QString hdevPath="C:/Users/DH/Desktop/";

    QByteArray ba = hdevPath.toLatin1();

    resource_path=ba.data();

MyEngine->AddProcedurePath(resource_path);

HTuple procedurenames=MyEngine->GetProcedureNames();

    QList<QString > nameList;

    int length= procedurenames.Length();

    for (int var = 0; var < length; ++var) {

        QString  name=procedurenames[var].S().ToUtf8();

        nameList.append(name);

    }

然后设置函数和函数回调指针,“test”为引擎文件名称,设置后会加载该引擎函数,后续可以使用回调执行。

try {

        Program = new HDevProcedure("test");

        ProcCall = new HDevProcedureCall(*Program);

    }catch (HDevEngineException Ex)

    {

        ui->lineEdit_4->setText( "HDevEngine Exception");

        return;

    }

执行之前调用函数接口,可以查看函数的输入输出参数个数、名称、类型、以及参数说明等等。本例子参数都没htuple,图形参数使用SetInputIconicParamObject,具体接口查看"HDevEngineCpp.h"文件中HDevProcedureCall;值得注意的是输入输出都可以使用序号(从1开始)或者ParamName.

//输入个数

   int num_input=Program->GetInputCtrlParamCount();

   ui->textEdit->append("num_input  :"+QString::number(num_input));

    //输出个数

   int num_output=Program->GetOutputCtrlParamCount();

   ui->textEdit->append("num_output  :"+QString::number(num_output));

    //输入的参数名字

   auto input_name= Program->GetInputCtrlParamNames();

   ui->textEdit->append("input_name  :");

   ui->textEdit->append(input_name.ToString().Text());

    //输出参数的名字

   auto ouput_name=Program->GetOutputCtrlParamNames();

   ui->textEdit->append("ouput_name  :");

   ui->textEdit->append(ouput_name.ToString().Text());

    //引擎信息--没有使用到

   auto QueryInfo= Program->QueryInfo();

   ui->textEdit->append("QueryInfo  :");

   ui->textEdit->append(QueryInfo.ToString().Text());

    //查询参数的信息,也就是关键字,

   auto QueryParamInfo= Program->QueryParamInfo();

   ui->textEdit->append("QueryParamInfo  :");

   ui->textEdit->append(QueryParamInfo.ToString().Text());

   //获取参数描述,其他字段如下

//       ["assertion", "default_type", "default_value", "description",

//       "file_ext", "file_ext_descr", "mixed_type", "multichannel",

//       "multivalue", "sem_type", "stepmin", "steprec", "type_list",

//       "valuefunction", "value_list", "valuemax", "valuemin", "valuenumber",

//       "values"]

   ui->lineEdit_5->setText("description");

   for(int k=1;k<=num_input;k++)

   {

       std::string str = ui->lineEdit_5->text().toStdString();

       const char* slot=str.c_str();

       auto abb=Program->GetInputCtrlParamName(k);

       auto a=Program->GetParamInfo(abb,slot);

       ui->textEdit->append(a.ToString().Text());

//       auto bb=Program->GetInputCtrlParamInfo(k,slot);

//       ui->textEdit->append(bb.ToString().Text());

   }

   QString a="查找模板OK";

   QString b="测量成功";

   HTuple  Param1,Param2,Param3,Param4,Result,Result1,Exception,ErrorString,path;

   Param1=a.toStdString().data();

   Param2=b.toStdString().data();

   Param3=b.toStdString().data();

   Param4=b.toStdString().data();

   ProcCall->SetInputCtrlParamTuple(1,Param1);

   ProcCall->SetInputCtrlParamTuple(2,Param2);

   ProcCall->SetInputCtrlParamTuple(3,Param3);

   ProcCall->SetInputCtrlParamTuple(4,Param4);

   ProcCall->SetInputCtrlParamTuple(5,path);

   ProcCall->Execute();//执行函数

   //       auto out1 = ProcCall->GetOutputCtrlParamTuple("Result");

   //       auto out2 = ProcCall->GetOutputCtrlParamTuple("Result1");

   //       ui->textEdit->append(out1.ToString().Text());

   //       ui->textEdit->append(out2.ToString().Text());

   for (int j=1;j<=num_output;j++) {

       HTuple out;

       ProcCall->GetOutputCtrlParamTuple(j,&out);

       ui->textEdit->append(out.ToString().Text());

   }

2.1.3重载

通过以上三步,引擎函数可以被调用;但是如果程序运行期间引擎进行更改,程序中不会更改;必须主动重新加载,有了这一步我们就不需要重复的启动关闭应用程序了。

分为两个步骤:SetProcedurePath会清空当前所有的路径

然后AddProcedurePath重新添加路径

注意:如果文件改动更新的话需要使用

       //获取程序名

    HTuple procedurenames=MyEngine->GetProcedureNames();

       //卸载程序

MyEngine->UnloadProcedure()

MyEngine->SetProcedurePath("");

    QString hdevPath="C:/Users/DH/Desktop/";

    QByteArray ba = hdevPath.toLatin1();

    resource_path=ba.data();

    MyEngine->AddProcedurePath(resource_path);

2.2调用hdev文件

2.2.1设置文件路径以及读取内部函数

QString hdevPath = ui->lineEdit->text();

    HDevProgram hDevProgram(hdevPath.toStdString().c_str());

    if(!hDevProgram.IsLoaded())

    {

        int a=1;

    }

    HTuple hv_UsedProcedureNames = hDevProgram.GetUsedProcedureNames();

    QList<QString> lstUsedProcedureName;

    for(Hlong index = 0; index < hv_UsedProcedureNames.Length(); ++index)

    {

        lstUsedProcedureName.push_back(hv_UsedProcedureNames[index].S().Text());

        ui->textEdit->append(hv_UsedProcedureNames[index].S().Text());

    }

    ui->textEdit->append("加载完成");

2.2.2执行hdev内部函数以及获取内部函数的信息;执行以及函数信息获取和hdvp一样;

 QString hdevPath = ui->lineEdit->text();

    HDevEngineCpp::HDevEngine().SetEngineAttribute("docu_language", "zh_CN");

    HDevProcedure* program = new HDevProcedure(hdevPath.toStdString().c_str(),"abcd");

    ui->textEdit->append("  -----");

    //输入个数

    int num_input=program->GetInputCtrlParamCount();

    ui->textEdit->append("输入个数  :"+QString::number(num_input));

        //输出个数

    int num_output=program->GetOutputCtrlParamCount();

    ui->textEdit->append("输出个数  :"+QString::number(num_output));

        //输入的参数名字

    auto input_name= program->GetInputCtrlParamNames();

    ui->textEdit->append("输入名字  :");

    ui->textEdit->append(input_name.ToString().Text());

        //输出参数的名字

    auto ouput_name=program->GetOutputCtrlParamNames();

    ui->textEdit->append("输出名字  :");

    ui->textEdit->append(ouput_name.ToString().Text());

        //查询参数的信息,也就是关键字,

    auto QueryParamInfo= program->QueryParamInfo();

    ui->textEdit->append("QueryParamInfo  :");

    ui->textEdit->append(QueryParamInfo.ToString().Text());

    HDevEngineCpp::HDevProcedureCall call = *program;

    call.Execute();

    for (int j=1;j<=program->GetOutputCtrlParamCount();j++) {

        HTuple out;

        call.GetOutputCtrlParamTuple(j,&out);

        //out=m_pProcCall->GetOutputCtrlParamTuple("Result");

        ui->textEdit->append(out.ToString().Text());

    }

注:如果hdev修改后需要重新加载,只需要重新设置HDevProgram(文件路径包含文件名)即可;

2.3C++掉库函数

2.3.1多个hdvp函数生成.hdpl库函数

首先建立空白库函数,点击“函数”---“管理函数”---“管理库函数”

新建的库函数目录如果不在外部函数目录,会提醒添加,建好后右上角选中新建的函数,然后右上角添加函数,即可选择hdev文件;点击选中的库右击保存库(所有的函数就会保存到一个文件中,方便迁移,迁移添加库函数即可使用)。

2.3.2QT调用库函数

同上述调用外部函数步骤一样,

注意:第二步的函数名称需要变更为库函数中所调用的函数名,并非库函数文件名,如下图的右侧

3.HALCON导出库工程

3.1主函数

如图3.1为示例主程序。

图 3.1 主函数

3.2函数封装

图3.2为封装的接口函数内容。

图 3.2 接口函数

3.3导出库工程

导出,选择文件--导出库工程

图 3.3 导出C++库工程

3.4C++项目引用HALCON依赖

pro添加

# HALCON
#include
INCLUDEPATH += $$(HALCONROOT)/include
INCLUDEPATH += $$(HALCONROOT)/include/halconcpp
INCLUDEPATH += $$(HALCONROOT)/include/hdevengine
#libs
LIBS += -L$$(HALCONROOT)/lib/$$(HALCONARCH) -lhalcon -lhalconcpp -lhdevenginecpp

3.5导入HALCON库工程.h、.cpp文件

将生成的工程文件添加到C++项目(除了直接复制还可以使用cmake编译生成工程,生成lib使用)

图3.4添加文件

3.6添加引用调用函数

设置路径

const char* resource_path="D:/Desktop/库工程/blob/res_blob/";
 
SetResourcePath(resource_path);

调用函数传入变量

 QString Path="C:/Users/Public/Documents/MVTec/HALCON-18.11-Progress/examples/images/diedie/die_03.png";
    HalconCpp::HTuple picPath=Path.toStdString().c_str();
    HalconCpp::HObject  Bond;
    HalconCpp::HObject FinalBalls;
    blob::ball(&Bond,&FinalBalls,picPath);

4.调试

4.1开启调试以及设置端口

在程序中添加该代码

   HDevEngine* MyEngine = new HDevEngine();

  MyEngine->StartDebugServer();//默认端口57786

程序添加函数后,必须使用HDevProcedure指定函数名称后才可以调试,打开halcon—>执行—>附加到进程。

5.执行本地hdev文件

5.1设置本地文件

    QString hdevPath="C:/Users/DH/Desktop/test.hdev";

    QByteArray ba = hdevPath.toLatin1();

    resource_path=ba.data();

    m_pProgram = new HDevProgram(resource_path);

    m_pProgramCall = new HDevProgramCall(*m_pProgram);

5.2执行以及取值

    m_pProgramCall->Execute();

    QString name="c";//变量名字

    auto aa=name.toLatin1();

    const char * var=aa.data();

    auto a = m_pProgramCall->GetCtrlVarTuple(var);//使用该函数内部传要取的参数名字

  • 30
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值