HALCON 的一个优势是大多数算子都能自动处理多个输入值(元组值)。例如,您可以使用单个或多个输入区域调用算子 AreaCenter;算子会自动返回所有传递区域的面积和中心坐标。同样,如果您使用多个矩形坐标值调用 GenRectangle1,它会创建多个区域。
以下各节将提供有关以下方面的更多详细信息
您可以在参考手册中查看算子是否也适用于元组。例如,我们在下面展示了算子 AreaCenter 和 GenRectangle1 的相关部分。
如您所见,像 HRegion 这样的图标类会自动处理多值;参数是否接受/返回多值并不能从签名中看到,只能在参数部分看到: 在这里,一个附加的 (-array) (在示例中: HRegion(-array)) 表示参数可以包含一个或多个值。
|
|
| regions (input_object) | region(-array) → HRegion |
| area (output_control) | integer(-array) → HTuple (int / long) |
| row (output_control) | point.y(-array) → HTuple (double) |
| column (output_control) | point.x(-array) → HTuple (double) |
|
|
| rectangle (output_object) | region(-array) → HRegion |
| row1 (input_control) | rectangle.origin.y(-array) → HTuple (double / int / long) |
| column1 (input_control) | rectangle.origin.x(-array) → HTuple (double / int / long) |
| row2 (input_control) | rectangle.corner.y(-array) → HTuple (double / int / long) |
| column2 (input_control) | rectangle.corner.x(-array) → HTuple (double / int / long) |
相比之下,控制参数通过数据类型显示其包含单个或多个值: 前者使用基本数据类型,如 double,后者使用 HALCON/.NET HTuple 类。因此,您可以通过两种方式通过 HRegion 调用 GenRectangle1,一种是传递 doubles,另一种是传递 HTuple s(此处使用构造函数形式):
HRegion SingleRegion = new HRegion(10.0, 10.0, 50.0, 50.0);
HRegion MultipleRegions = new HRegion(new HTuple(20.0, 30.0), new HTuple(20.0, 30.0),
new HTuple(60.0, 70.0), new HTuple(60.0, 70.0));
同样,可以通过两种方式调用 AreaCenter:
double Area, Row, Column; HTuple Areas, Rows, Columns; Area = SingleRegion.AreaCenter(out Row, out Column); Areas = MultipleRegions.AreaCenter(out Rows, out Columns);
下面,我们将提供有关图标元组("图标元组" 一节 )和控制元组("控制元组和 HTuple 类" 一节 )的更多信息。
图标类 HImage、HRegion 和 HXLD 可以包含单个或多个对象。要处理元组中的所有元素,首先要使用算子 CountObj 查询元素的数量
int NumRegions = MultipleRegions.CountObj();
然后使用 HALCON 算子 SelectObj 或(使用 C# 时)算子 [] 访问元素:
for (int i=1; i<=NumRegions; i++)
{
HRegion Region = MultipleRegions[i];
...
}
请注意,在图标元组中 ! 元素索引以 1 开始.
您可以使用 HALCON 算子 ConcatObj 创建或扩展图标元组:
HRegion ThreeRegions = SingleRegion.ConcatObj(MultipleRegions);
对于控制元组,HALCON/.NET 提供了 HTuple 类。HTuple 实例可以包含 double、int、string 和 HHandle 类型的元素。它们还可以包含多种元素类型。
以下各节将介绍
要处理一个元组的所有元素,首先要通过属性 Length 查询其长度:
int TupleLength = Areas.Length;
您可以使用算子 [] 访问元组元素:
for (int i=0; i<TupleLength; i++)
{
double Element = Areas[i];
...
}
请注意,如果尝试读取一个不存在的元组元素,或者尝试将一个元素赋值给一个不同类型的变量而不进行类型转换,都会出现异常。
HTuple 类提供了许多不同的构造函数(有关列表,请参见 Visual Studio 的对象浏览器)。下面一行创建了一个带有单一值的 int 元组:
HTuple Tuple1 = new HTuple(1);
相比之下,下面一行创建的是一个 double 元组:
HTuple Tuple2 = new HTuple(1.0);
您也可以向构造函数传递多个值。请注意,当混合使用 double 和 int 值时(如下面一行),会创建一个 double 元组:
HTuple Tuple3 = new HTuple(1.0, 2);
相反,当值列表还包含 string 时,就会创建一个混合类型的元组,其中第二个值被存储为 int:
HTuple Tuple4 = new HTuple(1.0, 2, "s");
元组或元组元素的类型可通过其属性 Type 查询:
HTupleType TupleType = Tuple4.Type; HTupleType TupleElementType = Tuple4[1].Type;
通过在构造函数中传递元组,您可以非常简单地连接元组:
HTuple Tuple5 = new HTuple(Tuple2, Tuple3);
您还可以通过写入一个不存在的元素,将元素追加到元组中:
Tuple3[2] = 3;
HTuple 类提供了许多隐式转换方法,因此您可以在大多数地方直观地使用基本数据类型。例如,这行
double Element = Areas[i];
会自动将元素(实际上是 HTupleElement 类的实例)转换为 double。
同样,基本类型也会自动转换为 HTuple 实例。这种转换的缺点是,编译器通常无法判断你是想使用算子的简单版本还是元组版本,因此会出现相应的错误。例如,如果使用下面这一行,值既可以从 int 转换为 double,也可以转换为 HTuple:
// HRegion SingleRegion = new HRegion(10, 10, 50, 50);
您可以通过在第一个参数后面加上 .0 来非常简单的解决歧义:
HRegion SingleRegion = new HRegion(10.0, 10.0, 50.0, 50.0);
在 Matching 示例中,还有两个有歧义的例子,都是因为 basic-type 和 HTuple 参数混杂在同一个调用中。在第一种情况中,通过显式地将 double 参数转换为 HTuple 实例,解决了歧义问题:
private double row, column;
HTuple angleCheck;
HHomMat2D matrix = new HHomMat2D();
matrix.VectorAngleToRigid(new HTuple(row), new HTuple(column), new HTuple(0.0),
result.GetGenericShapeModelResult(0, "row"),
result.GetGenericShapeModelResult(0, "column"),
angleCheck);
在第二种情况下,HTuple 实例(只包含单个值)通过使用属性 D 显式地转换为 doubles,属性 D 将第一个元素的值返回为 double(实际上,这是 tuple[0].D 的快捷方式):
private double rectPhi, rectLength1, rectLength2; HTuple rect1RowCheck, rect1ColCheck; rectangle1.GenRectangle2(rect1RowCheck.D, rect1ColCheck.D, rectPhi + angleCheck.D, rectLength1, rectLength2);
通过类似的属性,您可以将元组元素转换成其他基本类型。但要注意的是,如果尝试将元素转换为 "错误" 类型,就会出现异常。
与输入参数不同,输出参数不会自动转换。有时,这会导致意外结果。例如,在下面的代码中,在调用 AreaCenter 时,输出参数和返回值都使用了 doubles :
HRegion MultipleRegions = new HRegion(new HTuple(20.0, 30.0), new HTuple(20.0, 30.0),
new HTuple(60.0, 70.0), new HTuple(60.0, 70.0));
double Area, Row, Column;
HTuple Areas, Rows, Columns;
Area = MultipleRegions.AreaCenter(out Row, out Column);
因此,只会返回第一个区域的面积和中心点。如果将返回值赋值给 HTuple,但输出参数仍为 doubles ,也会发生同样的情况:
Areas = MultipleRegions.AreaCenter(out Row, out Column);
相反,如果您为输出参数传递 HTuple s 并将返回值赋值给 double,算子会返回所有区域的中心坐标,但只返回第一个区域的面积:
Area = MultipleRegions.AreaCenter(out Rows, out Columns);
HALCON 提供了许多用于处理元组的算子。在参考手册的 元组 一章中可以找到这些算子。HDevelop 用户向导 对这些算子进行了概述。请注意,这里使用的不是算子名称,而是相应 HDevelop 函数的名称,其中省略了 Tuple 并使用小写字母,例如,使用 rad 代替 TupleRad。
对于基本算术运算,HALCON/.NET 提供了算子重载。例如,算子 + 会自动调用 HALCON 算子 TupleAdd。