halcon引擎学习笔记(八)使用向量变量

勇哥这套halcon引擎的学习笔记贴子共七篇,它是在官方指导文档《http://www.skcircle.com/?id=1343》的基础上学习编写而成的笔记。只是有一篇讲解怎么调用向量变量的没有加入,因为勇哥实在不知道这个向量变量有啥子用。以后如果搞明白了再加入吧。


2020/7/3勇哥注:

原来halcon中的向量就是个容器,跟c++标准模板库中的那个向量是一致的。第八篇加上来吧

halcon引擎学习笔记(八)使用向量变量


halcon引擎学习笔记(七)在在HDevEngine/C#中使用实时编译器JIT 

halcon引擎学习笔记(六)多线程并发执行外部函数,多窗口显示  

halcon引擎学习笔记(五)多线程并发执行外部函数  

halcon引擎学习笔记(四)调用时的错误处理   

halcon引擎学习笔记(三)执行本地或者外部程序   

halcon引擎学习笔记(二)执行Procedure程序,扩展名为hdvp的halcon函数   

halcon引擎学习笔记(一)执行hdev程序   

演示程序勇哥用的是halcon19.11,C#使用的是vs2013版本。

全部测试代码勇哥已经打包,请点击下载


如果你要调用的程序是一个hdev主程序,且当中没有外部函数或者自定义函数,则可以看(一)

如果你要调用的程序是一个hdev主程序,且当中有若干的外部函数或者自定义函数,则可以看(三)

如果你要调用的程序只是一个hdvp的外部函数,则可以看(二)

如果你需要多线程调用外部函数,则可以看(六)(七)

如果你的程序中用到向量变量,则可以看(八)


2020/10/15勇哥注:

勇哥最近寻遍halcon引擎类的功能,发现无法实现修改halcon程序并保存后,C#这边能实时运行修改后的halcon程序。

必须要退出C#程序后,再次执行才是跑的修改后的代码。

这真是个遗憾,因为机器正在做货时,重启C#程序是相当不方便的一件事。

如果有人知道怎么实现,麻烦告诉勇哥,非常感谢!


2020/12/18勇哥注:

由网友“小黄鱼”指出,HDevEngine 类有个UnloadProcedure方法调用后,可以实现不需要重启C#程序即可执行更新后的外部函数。

经我测试后,发现是有效的!

在这里非常感谢他的指点!!!


正文部分

========================



之前勇哥对halcon的向量变量不了解。后来对这方面的知识进行了一点补充,见下面的贴子:

halcon的向量变量 Vector

了解了之后,就补上这系列教程的第8篇吧。



image.png

image.png


演示源码:

// 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的参数

image.png

源码:

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

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
  • 评论列表:
  •  xiongqing
     发布于 2022-03-29 18:22:37  回复该评论
  • 勇哥,哪里有halcon库函数的介绍,halcon自带的讲的不清楚

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年3月    »
123
45678910
11121314151617
18192021222324
25262728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864