勇哥这套halcon引擎的学习笔记贴子共七篇,它是在官方指导文档《http://www.skcircle.com/?id=1343》的基础上学习编写而成的笔记。只是有一篇讲解怎么调用向量变量的没有加入,因为勇哥实在不知道这个向量变量有啥子用。以后如果搞明白了再加入吧。
2020/7/3勇哥注:
原来halcon中的向量就是个容器,跟c++标准模板库中的那个向量是一致的。第八篇加上来吧
halcon引擎学习笔记(七)在在HDevEngine/C#中使用实时编译器JIT
halcon引擎学习笔记(六)多线程并发执行外部函数,多窗口显示
halcon引擎学习笔记(二)执行Procedure程序,扩展名为hdvp的halcon函数
演示程序勇哥用的是halcon19.11,C#使用的是vs2013版本。
全部测试代码勇哥已经打包,请点击《下载》
如果你要调用的程序是一个hdev主程序,且当中没有外部函数或者自定义函数,则可以看(一)
如果你要调用的程序是一个hdev主程序,且当中有若干的外部函数或者自定义函数,则可以看(三)
如果你要调用的程序只是一个hdvp的外部函数,则可以看(二)
如果你需要多线程调用外部函数,则可以看(六)(七)
如果你的程序中用到向量变量,则可以看(八)
2020/10/15勇哥注:
勇哥最近寻遍halcon引擎类的功能,发现无法实现修改halcon程序并保存后,C#这边能实时运行修改后的halcon程序。
必须要退出C#程序后,再次执行才是跑的修改后的代码。
这真是个遗憾,因为机器正在做货时,重启C#程序是相当不方便的一件事。
如果有人知道怎么实现,麻烦告诉勇哥,非常感谢!
2020/12/18勇哥注:
由网友“小黄鱼”指出,HDevEngine 类有个UnloadProcedure方法调用后,可以实现不需要重启C#程序即可执行更新后的外部函数。
经我测试后,发现是有效的!
在这里非常感谢他的指点!!!
正文部分
========================
之前勇哥对halcon的向量变量不了解。后来对这方面的知识进行了一点补充,见下面的贴子:
了解了之后,就补上这系列教程的第8篇吧。


演示源码:
// HDevEngine/.NET (C#) example for executing HDevelop programs
//
//?2007-2019 MVTec Software GmbH
//
// Purpose:
// This example program shows how vector variables are supported by the
// classes HDevEngine, HDevProgram, HDevProgramCall, HDevProcedure, and
// HDevProcedureCall.
// The program uses two vectors: an object vector containing the input
// images and a tuple vector containing scaling factors for the processing.
// In the HDevelop code the gray values of the input images are scaled
// by the factors provided in the input tuples. Afterwards the factors
// are transformed into string values. In case of the program call the
// two global variables are used for input and output, the unaltered
// input values are stored in the two program variables.
// When you click the button Load, the HDevelop program and procedure are
// loaded, when you click Execute they are executed.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using HalconDotNet;
namespace UseVectorVariables
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class UseVectorVariablesForm : System.Windows.Forms.Form
{
internal System.Windows.Forms.Button LoadBtn;
internal System.Windows.Forms.Button ExecuteBtn;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
// HDevEngine
// Instance of the engine
private HDevEngine MyEngine = new HDevEngine();
// Instance of the program call
private HDevProgram Program;
private HDevProgramCall ProgramCall;
// Instance of the procedure call
private HDevProcedure Procedure;
private HDevProcedureCall ProcCall;
// Path of HDevelop program
String ProgramPathString;
private HSmartWindowControl WindowControl;
// HALCON window
private HWindow Window;
public UseVectorVariablesForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.LoadBtn = new System.Windows.Forms.Button();
this.ExecuteBtn = new System.Windows.Forms.Button();
this.WindowControl = new HalconDotNet.HSmartWindowControl();
this.SuspendLayout();
//
// LoadBtn
//
this.LoadBtn.Location = new System.Drawing.Point(678, 11);
this.LoadBtn.Name = "LoadBtn";
this.LoadBtn.Size = new System.Drawing.Size(192, 55);
this.LoadBtn.TabIndex = 3;
this.LoadBtn.Text = "Load Program";
this.LoadBtn.Click += new System.EventHandler(this.LoadBtn_Click);
//
// ExecuteBtn
//
this.ExecuteBtn.Location = new System.Drawing.Point(678, 89);
this.ExecuteBtn.Name = "ExecuteBtn";
this.ExecuteBtn.Size = new System.Drawing.Size(192, 55);
this.ExecuteBtn.TabIndex = 6;
this.ExecuteBtn.Text = "Execute Program";
this.ExecuteBtn.Click += new System.EventHandler(this.ExecuteBtn_Click);
//
// WindowControl
//
this.WindowControl.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.WindowControl.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange;
this.WindowControl.HDoubleClickToFitContent = true;
this.WindowControl.HDrawingObjectsModifier = HalconDotNet.HSmartWindowControl.DrawingObjectsModifier.None;
this.WindowControl.HImagePart = new System.Drawing.Rectangle(0, 0, 768, 576);
this.WindowControl.HKeepAspectRatio = true;
this.WindowControl.HMoveContent = true;
this.WindowControl.HZoomContent = HalconDotNet.HSmartWindowControl.ZoomContent.WheelForwardZoomsIn;
this.WindowControl.Location = new System.Drawing.Point(26, 11);
this.WindowControl.Margin = new System.Windows.Forms.Padding(2);
this.WindowControl.Name = "WindowControl";
this.WindowControl.Size = new System.Drawing.Size(614, 399);
this.WindowControl.TabIndex = 7;
this.WindowControl.WindowSize = new System.Drawing.Size(614, 399);
this.WindowControl.Load += new System.EventHandler(this.WindowControl_Load);
//
// UseVectorVariablesForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(8, 18);
this.ClientSize = new System.Drawing.Size(890, 434);
this.Controls.Add(this.WindowControl);
this.Controls.Add(this.ExecuteBtn);
this.Controls.Add(this.LoadBtn);
this.Name = "UseVectorVariablesForm";
this.Text = "Use Vector Variables in an HDevelop Program via HDevEngine";
this.Load += new System.EventHandler(this.UseVectorVariablesForm_Load);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new UseVectorVariablesForm());
}
private void UseVectorVariablesForm_Load(object sender, System.EventArgs e)
{
// path of external procedures
string halconExamples = HSystem.GetSystem("example_dir");
string ProcedurePath = halconExamples + @"\hdevengine\procedures";
ProgramPathString = halconExamples +
@"\hdevengine\hdevelop\use_vector_variables.hdev";
if (!HalconAPI.isWindows)
{
// Unix-based systems (Mono)
ProcedurePath = ProcedurePath.Replace('\\', '/');
ProgramPathString = ProgramPathString.Replace('\\', '/');
}
MyEngine.SetProcedurePath(ProcedurePath);
// disable Execute button
ExecuteBtn.Enabled = false;
}
private void WindowControl_Load(object sender, System.EventArgs e)
{
Window = WindowControl.HalconWindow;
// Warning: Convenience implementation for rerouting display
// operators is not thread-safe, use it only to execute programs
// in the main thread.
MyEngine.SetHDevOperators(new HDevOpMultiWindowImpl(Window));
}
private void LoadBtn_Click(object sender, System.EventArgs e)
{
try
{
Program = new HDevProgram(ProgramPathString);
ProgramCall = new HDevProgramCall(Program);
Procedure = new HDevProcedure("use_vector_variables");
ProcCall = new HDevProcedureCall(Procedure);
}
catch (HDevEngineException Ex)
{
MessageBox.Show(Ex.Message, "HDevEngine Exception");
return;
}
// Enable Execute button
ExecuteBtn.Enabled = true;
}
private void ExecuteBtn_Click(object sender, System.EventArgs e)
{
try
{
//
// HDevEngine/global variables
//
// Set global variables
int dim = 1;
// The actual dimension of global vector variables can be
// inquired from the HDevEngine class.
dim = MyEngine.GetGlobalIconicVarDimension("GObjectVector");
HObjectVector gObjectVector = new HObjectVector(dim);
HImage image = new HImage();
image.ReadImage("datacode/qrcode/qr_workpiece_09");
gObjectVector[1].O = image;
image.ReadImage("datacode/qrcode/qr_workpiece_02");
gObjectVector[0].O = image;
dim = MyEngine.GetGlobalCtrlVarDimension("GTupleVector");
HTupleVector gTupleVector = new HTupleVector(dim);
gTupleVector[1][0].T = 3.0;
gTupleVector[0][0].T = 0.3;
MyEngine.SetGlobalIconicVarVector("GObjectVector", gObjectVector);
MyEngine.SetGlobalCtrlVarVector("GTupleVector",gTupleVector);
// Execute program
ProgramCall.Execute();
// Get global variables
gObjectVector = MyEngine.GetGlobalIconicVarVector("GObjectVector");
gTupleVector = MyEngine.GetGlobalCtrlVarVector("GTupleVector");
//
// HDevProgram and HDevProgramCall
//
// The actual dimension of program variables can be inquired
// from the HDevProgram class. Either as a tuple with the
// dimensions of all iconic or control variables...
HTuple ctrlDimensions = new HTuple();
ctrlDimensions = Program.GetCtrlVarDimensions();
HTuple iconicDimensions = new HTuple();
iconicDimensions = Program.GetIconicVarDimensions();
// Get program variables
for (int i = 1; i <= Program.GetIconicVarCount(); i++)
if (Program.GetIconicVarName(i) == "ObjectVector")
{
// ... or for each variable separately.
dim = Program.GetIconicVarDimension(i);
break;
}
HObjectVector objectVector = new HObjectVector(dim);
objectVector = ProgramCall.GetIconicVarVector("ObjectVector");
for (int i = 1; i <= Program.GetCtrlVarCount(); i++)
if (Program.GetCtrlVarName(i) == "TupleVector")
{
dim = Program.GetCtrlVarDimension(i);
break;
}
HTupleVector tupleVector = new HTupleVector(dim);
tupleVector = ProgramCall.GetCtrlVarVector("TupleVector");
// Display result
Window.ClearWindow();
Window.SetTposition(5, 5);
Window.WriteString("Program execution");
Window.SetTposition(60, 5);
Window.WriteString("Scaling factors");
Window.SetTposition(110, 5);
Window.WriteString("Input (control): ");
Window.WriteString(tupleVector.ToString());
Window.SetTposition(150, 5);
Window.WriteString("Output (control): ");
Window.WriteString(gTupleVector.ToString());
HSystem.WaitSeconds(3.0);
for (int i = 0; i < objectVector.Length; i++)
{
Window.ClearWindow();
Window.DispObj(objectVector[i].O);
Window.SetTposition(480, 5);
Window.WriteString("Program execution: input image");
HSystem.WaitSeconds(1.5);
Window.ClearWindow();
Window.DispObj(gObjectVector[i].O);
Window.SetTposition(480, 5);
Window.WriteString("Program execution: scaled output image");
HSystem.WaitSeconds(1.5);
}
//
// HDevProcedure and HDevProcedureCall
//
// Set input parameters
// The actual dimension of procedure parameters can be inquired
// from the HDevProcedure class.
HTuple dims = Procedure.GetInputCtrlParamDimensions();
dims = Procedure.GetInputIconicParamDimensions();
dim = Procedure.GetInputIconicParamDimension(1);
HObjectVector inObjectVector = new HObjectVector(dim);
image = new HImage();
image.ReadImage("datacode/ecc200/ecc200_cpu_016");
inObjectVector[1].O = image;
image.ReadImage("datacode/ecc200/ecc200_cpu_017");
inObjectVector[0].O = image;
dim = Procedure.GetOutputCtrlParamDimension(1);
HTupleVector inTupleVector = new HTupleVector(dim);
inTupleVector[1][0].T = 2.0;
inTupleVector[0][0].T = 0.5;
// Parameters can be accessed via the parameter name...
ProcCall.SetInputIconicParamVector("InputObjectVector", inObjectVector);
ProcCall.SetInputCtrlParamVector("InputTupleVector", inTupleVector);
// ...or the parameter index.
ProcCall.SetInputIconicParamVector(1, inObjectVector);
ProcCall.SetInputCtrlParamVector(1, inTupleVector);
ProcCall.Execute();
// Get output parameters
dims = Procedure.GetOutputCtrlParamDimensions();
dims = Procedure.GetOutputIconicParamDimensions();
dim = Procedure.GetOutputIconicParamDimension(1);
HObjectVector outObjectVector = new HObjectVector(dim);
dim = Procedure.GetOutputCtrlParamDimension(1);
HTupleVector outTupleVector = new HTupleVector(dim);
outObjectVector = ProcCall.GetOutputIconicParamVector("OutputObjectVector");
outTupleVector = ProcCall.GetOutputCtrlParamVector("OutputTupleVector");
outObjectVector = ProcCall.GetOutputIconicParamVector(1);
outTupleVector = ProcCall.GetOutputCtrlParamVector(1);
// Display result
Window.ClearWindow();
Window.SetTposition(5, 5);
Window.WriteString("Procedure execution");
Window.NewLine();
Window.NewLine();
Window.SetTposition(60, 5);
Window.WriteString("Scaling factors");
Window.SetTposition(110, 5);
Window.WriteString("Input (control): ");
Window.WriteString(inTupleVector.ToString());
Window.SetTposition(150, 5);
Window.WriteString("Output (control): ");
Window.WriteString(outTupleVector.ToString());
HSystem.WaitSeconds(3.0);
for (int i = 0; i < inObjectVector.Length; i++)
{
Window.ClearWindow();
Window.DispObj(inObjectVector[i].O);
Window.SetTposition(480, 5);
Window.WriteString("Procedure execution: input image");
HSystem.WaitSeconds(1.5);
Window.ClearWindow();
Window.DispObj(outObjectVector[i].O);
Window.SetTposition(480, 5);
Window.WriteString("Procedure execution: scaled output image");
HSystem.WaitSeconds(1.5);
}
}
catch (HDevEngineException Ex)
{
MessageBox.Show(Ex.Message, "HDevEngine Exception");
return;
}
catch (HOperatorException)
{
// Window Handle cleared during execution ...?
// --> do nothing else.
}
}
}
}主程序use_vector_variables.hdev 源码:
global object vector(1) GObjectVector global tuple vector(2) GTupleVector * * save the original values of the global variables in program variables for I := 0 to GObjectVector.length() - 1 by 1 ObjectVector.at(I) := GObjectVector.at(I) TupleVector.at(I) := GTupleVector.at(I) endfor * * process the global variables use_vector_variables (GObjectVector, GObjectVector, GTupleVector, GTupleVector) *
注意: 这个主程序,居然不能直接跑起来,会报GObjectVector没有初始化的值。
但是我们C#调用的时候,因为提前设置了这个对象的值,就可以正常跑起来。
use_vector_variables.hdvp的参数

源码:
if (InputObjectVector.length() != InputTupleVector.length()) throw (30000) endif for I := 0 to InputObjectVector.length() - 1 by 1 Image := InputObjectVector.at(I) scale_image (Image, OutputObjectVector.at(I), InputTupleVector.at(I).at(0), 0) OutputTupleVector.at(I).at(0) := InputTupleVector.at(I).at(0)$'10.2f' endfor return ()
程序中的重点知识点:
(1) 注意点击执行按钮后,程序前面一部分代码调用执行的代码是use_vector_variables.hdev,而并不是use_vector_variables.hdvp
而在后面一部分代码,则调用的是use_vector_variables.hdvp。
(2) dim = MyEngine.GetGlobalIconicVarDimension("GObjectVector"); 这句读取了全局变量GObjectVector,它是个向量变量。
(3) 保存图片的向量在C#中是HObjectVector对象
而保存HTuple向量在C#中是HTupleVector对象
ImageVector[I].O=image 其中的字母O指的是HObject对象的意思,就像HTuple.D指的是double。
注意是大写的O,不是零。
这里执行完gObjectVector[1].O = image; 后,是复制图片一份,而不是传地址。
HObjectVector gObjectVector = new HObjectVector(dim);
HImage image = new HImage();
image.ReadImage("datacode/qrcode/qr_workpiece_09");
gObjectVector[1].O = image;
image.ReadImage("datacode/qrcode/qr_workpiece_02");
gObjectVector[0].O = image;(4) 这个是读取全局向量变量(元素为HTuple的向量)
然后声明一个HTupleVector向量,进行赋值。
gTupleVector[1][0].T 这其中的T,指的是HTuple的意思。而且这还是一个二维向量。
dim = MyEngine.GetGlobalCtrlVarDimension("GTupleVector");
HTupleVector gTupleVector = new HTupleVector(dim);
gTupleVector[1][0].T = 3.0;
gTupleVector[0][0].T = 0.3;以上可见,在HDevProgram中容易使用的数据类型Vector,在C#中封装成对象后,使用起来就复杂些,增加了许多对象与其对应的方法。
难怪官方要特意花篇幅讲解如何用halcon引擎调用向量变量。
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


少有人走的路


















