Halcon之可视化

可视化

  • 1、基本概念
    • 1.1、处理图形窗口
    • 1.2、显示
    • 1.3、A First Example
  • 2、扩展概念
    • 2.1、处理图形窗口
    • 2.2、显示
    • 2.3、 鼠标交互
    • 2.4、Gnuplot
  • 3、编程示例
    • 3.1、显示 HALCON 数据结构
  • 4、选择算子
    • 4.1、处理图形窗口
    • 4.2、显示
    • 4.3、鼠标交互
    • 4.4、Gnuplot
  • 5、提示与技巧
    • 5.1、保存窗口内容
    • 5.2 执行时间处理时间
  • 6、高级主题
    • 6.1、编程环境
    • 6.2、无闪烁可视化
    • 6.3、远程可视化
    • 6.4、程序化可视化

在 HALCON 中显示数据非常简单:在 HALCON 提供的图形窗口中,所有支持的数据类型都可以使用特定的显示操作符直接可视化。 这些窗口的创建和显示都只需要很少的编程工作,因为功能已针对机器视觉中的使用进行了优化。
使用 HALCON 可视化提供了几个优势。 首先,它在开发过程中节省了大量时间,因为所有重要的可视化方法都已经预先定义好了。 此外,该功能独立于操作系统:使用 HALCON 的可视化在 Windows 下编写程序可以轻松移植到 Linux,因为可视化操作符的行为相同,因此只需要重写使用操作系统功能的用户代码。

1、基本概念

对于可视化,需要考虑两个重要方面:图形窗口和必须可视化的数据。
Halcon之可视化_第1张图片

1.1、处理图形窗口

HALCON 提供了一个易于使用的操作符来创建用于可视化的图形窗口:open_window。 此运算符采用所有必要参数来指定尺寸、模式以及与潜在父窗口的关系。 因此,将返回一个 WindowHandle,您可以使用它在显示到窗口中或更改可视化参数时引用该窗口。 请注意,窗口的尺寸不受虚拟显示大小的限制。 因此,您还可以在具有多个屏幕的系统上工作。 控制窗口最重要的操作符是 clear_window 将其重置为其背景颜色, set_part 指定显示坐标系和 close_window 当不再需要窗口时。 运算符 set_window_param 允许设置打开窗口的不同参数。

1.2、显示

对于每种 HALCON 数据类型,都提供了用于显示的特定运算符。 图标数据(图像、区域和 XLD)最方便的操作符是 disp_obj。 此运算符自动处理灰色或彩色图像、区域和 XLD。 为了控制数据在窗口中的显示方式,使用带有前缀 set_(或 dev_set_ 用于 HDevelop 中的可视化)的运算符。 它们允许控制颜色、绘制模式、线宽和许多其他参数。

1.3、A First Example

这个基本概念的一个例子是以下程序,它展示了如何可视化覆盖有分割结果的图像。 这里使用了 HDevelop 中提供的可视化操作符。
Halcon之可视化_第2张图片
图 19.1:可视化分段剪辑

从文件中读取图像后,使用 binary_threshold 选择暗剪辑,它会自动选择阈值。 确定连通分量并选择合适大小的区域后,结果可视化。 首先,显示图像。 此后,区域的参数设置为多色 (12) 和边距模式。 最后,区域将显示这些设置。

read_image (Image, 'clip') 
binary_threshold (Image, Dark, 'max_separability', 'dark', UsedThreshold) 
connection (Dark, Single)
select_shape (Single, Selected, 'area', 'and', 5000, 10000) 
dev_display (Image) 
dev_set_colored (12) 
dev_set_draw ('margin') 
dev_display (Selected)

2、扩展概念

在高级应用程序中,需要完全控制可视化过程。 这可以包括在使用 Microsoft Visual Basic 或 Microsoft C++ 开发的程序中使用图形窗口、更改图形窗口的行为、使用缓冲输出,甚至使用外部程序进行可视化。 除了易于使用之外,HALCON 还提供对所有这些主题的完全控制,以提供高级的灵活性。

2.1、处理图形窗口

在本节中,我们将更详细地考虑图形窗口的概念。

  • 图形窗口的设计使得每个窗口都将所有相应的参数存储在一种图形上下文中。每当调用 set_draw 之类的运算符时,都会修改此上下文以用于此窗口,直到该值被覆盖为止。所有修改图形上下文的操作符都以前缀 set_ 开头。可以使用带有前缀 get_ 的相应运算符(例如 get_draw)来请求上下文的当前值。
  • 除了显示参数,每个图形窗口都有一个坐标系,可以用set_part 定义。图像的左上角是(0,0),右下角是(height-1,width1)。可以使用 get_image_size 请求图像的大小。请注意,与 HDevelop 不同,此坐标系必须通过调用 set_part 来指定。否则,可视化的图像部分是未定义的。
  • 运算符open_window 有一个名为Father 的参数。默认情况下,使用值 0,这意味着窗口没有父窗口,并且作为独立实例浮动。您可以通过将一个窗口的句柄作为父窗口传递给另一个窗口来构建窗口的层次结构。除此之外,还可以使用父机制将图形窗口嵌入到其他形式中(参见第 317 页的 19.6 节)。要设置打开窗口的不同参数,请使用 set_window_param。

2.2、显示

打开图形窗口后,返回的窗口句柄用于与其通信。通常,在显示数据之前首先指定可视化参数。要控制图像,只需要几个操作符:set_paint(用于配置文件和 3D 绘图)、set_lut(用于查找表)和 set_part_style(用于缩放插值)。要指定区域的输出,可以使用许多参数。最重要的是 set_draw(对于填充或边距模式)、set_color(对于笔的颜色)、set_line_width(对于笔的宽度)和 set_colored(对于多色模式)。要显示 XLD 数据,使用相同的参数(set_draw 除外)。
使用显示模式“3d_plot”,您可以创建 3D 高度场的交互式显示。运算符 update_window_pose 允许以直观的方式操纵此类 3D 绘图的姿势,运算符 unproject_coordinates 计算 3D 绘图窗口中某个点的图像坐标。示例 hdevelop/Graphics/Parameters/set_paint_3d_plot.hdev 展示了如何使用这些运算符。请注意,在使用 HDevelop 时,您还可以使用 HDevelop 用户指南中描述的按钮直接切换到 3d_plot 模式下高度字段的交互式显示(请参阅第 195 页上的第 6.8 节)。
可视化本身是使用 disp_image、disp_color、disp_region 或 disp_xld 等运算符执行的。最方便的方法是使用disp_obj,它会自动使用正确的方法。
对于文本输出,首先使用 set_font 指定字体。图形窗口中的所需位置由 set_tposition 确定。使用 write_string 将文本写入窗口执行无闪烁显示,请参阅第 317 页上的第 19.6 节。

2.3、 鼠标交互

要知道的最重要的事情是 HALCON 不使用事件驱动的方法来处理鼠标。每个操作符都被设计成鼠标交互在操作符被调用时开始并在操作符返回时结束。如果需要事件驱动模式,则必须使用操作系统提供的标准机制。
与鼠标交互主要涉及两个任务:

  • 第一个任务是请求鼠标的位置。这可以使用 get_mposition 如果像素精确的结果就足够了,或者使用 get_mposition_sub_pix 来实现亚像素精确的输出。这些操作符立即返回并获得位置和鼠标按钮作为结果。另一种方法是 get_mbutton 和 get_mbutton_sub_pix 用于亚像素精确位置。这些运算符仅在单击鼠标按钮时返回。
  • 第二个重要操作是用鼠标绘制形状。这是通过名称以 draw_ 开头的特殊运算符完成的。提供了许多不同形状(如圆形或矩形)的运算符。此外,结果可以使用不同的数据类型,如区域或 XLD 轮廓。

2.4、Gnuplot

为了可视化数值,HALCON 提供了一个公共领域软件 Gnuplot 的接口。 该工具对于绘制分布等值的元组特别有用,并且还提供了图像 3D 绘图的扩展版本。

3、编程示例

本节简要介绍使用 HALCON 提供的可视化运算符。

3.1、显示 HALCON 数据结构

Example: solution_guide/basics/display_operators.hdev

* display_operators.hdev: shows the different ways of visualizing
* 
read_image (Image, 'fabrik')
open_graphics_window (Image, WindowHandle)
display_image (Image, WindowHandle)
regiongrowing (Image, Regions, 1, 1, 3, 100)
display_regions (Image, Regions, WindowHandle)
edges_sub_pix (Image, Edges, 'lanser2', 0.5, 10, 30)
display_xld (Image, Edges, WindowHandle)
display_text (Image, Regions, WindowHandle)

示例程序旨在展示显示图像、区域、XLD 和文本的主要功能。 它由一个小的主程序组成,该程序调用处理四种不同数据类型的过程。 该程序是为 HDevelop 编写的,并使用其特定的显示操作符。 这是通过自然地移植(例如,通过自动导出)到其他语言接口(如 C++、C# 或 Visual Basic)的方式完成的。
主程序包含五个程序:open_graphics_window、display_image、display_regions、display_xld和display_text。 要在各个程序的程序之间切换,您可以使用程序窗口中的组合框程序。 下面,对每个程序的选定部分进行说明。
open_graphics_window 是用于打开与图像大小相同的图形窗口的支持程序。 这是通过调用 get_image_size 访问图像尺寸来完成的。 在打开新窗口之前,关闭现有窗口。 为了相应地调整坐标系,调用 dev_set_part。 这将在 HDevelop 中自动完成,但对于其他编程环境,这一步是必要的。 最后,HDevelop 自动显示每个结果的默认行为被关闭。 这会导致只有编程输出可见。

get_image_size (Image, Width, Height) 
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'white', WindowHandle) 
dev_set_part (0, 0, Height - 1, Width - 1) 
dev_update_window ('off')

然后,图像的显示过程称为:display_image。 它有 Image 和 WindowHandle 作为输入参数。 首先,窗口被激活,这对于 HDevelop 来说也是不需要的,但对于其他编程环境很重要。 现在,图像显示在图形窗口中。

dev_set_window (WindowHandle) 
dev_display (Image)

更改查找表 (LUT),请调用 dev_set_lut,再次调用 dev_display 后效果将变得可见。
接下来,使用所谓的 3D 绘图显示图像的一部分(见图 19.2)。 这里,灰度值被视为高度信息。 对于此模式,使用另一个 LUT。

Halcon之可视化_第3张图片
图 19.2:(a) 带有 ROI 的原始图像; (b) ROI 内的 3D 图像图

显示区域的过程称为 display_regions。 它首先将图像显示为背景,然后设置区域的显示参数。 dev_set_draw 指定只可视化区域边界。 dev_set_colored 激活多色模式,其中每个区域以不同的颜色显示(循环变化)。 作为简单显示区域原始形状的替代方法,HALCON 允许您使用 dev_set_shape 修改形状。 在给定的示例中,选择了等效的椭圆。 结果如图 19.3 所示。

dev_display (Image) 
dev_set_draw ('margin') 
dev_set_colored (6) 
dev_display (Regions) 
dev_display (Image) 
dev_set_shape ('ellipse') 
dev_display (Regions)

Halcon之可视化_第4张图片
图 19.3:(a)区域和(b)它们的等效椭圆

过程 display_xld 首先使用多色模式显示覆盖在图像上的所有轮廓。 然后,使用 dev_set_part 定义缩放。 这种缩放模式允许轻松检查亚像素精确轮廓。 为了提供附加信息,选择给定大小的轮廓,并使用 get_contour_xld 为每个轮廓提取控制点。 坐标在这里作为实数值的元组返回。 对于这些控制点中的每一个,使用 gen_cross_contour_xld 生成一个十字,然后将其叠加到轮廓上。

dev_display (Contours) 
gen_rectangle1 (Rectangle, 239, 197, 239 + 17, 197 + 17) 
dev_set_part (239, 197, 239 + 17, 197 + 17) 
select_shape_xld (Contours, SelectedXLD, 'area', 'and', 2000, 3000) 
count_obj (SelectedXLD, Number) 
for k := 1 to Number by 1
select_obj (SelectedXLD, SingleContour, k) 
get_contour_xld (SingleContour, Row, Col)
for i := 0 to |Row| - 1 by 1
gen_cross_contour_xld (Cross, Row[i], Col[i], 0.8, rad(45)) 
dev_display (Cross)
endfor
endfor

Halcon之可视化_第5张图片
图 19.4:亚像素精确轮廓控制点:(a)原始图像; (b) 缩放图像部分

程序的最后一部分是一个名为 display_text 的过程。 它展示了如何处理鼠标和文本输出。 任务是用鼠标单击图形窗口以选择特定区域并计算特征,然后将其显示在图形窗口中。 首先,选择字体。 由于字体名称处理不兼容,这是可视化中唯一不能在 Linux、OS X 和 Windows 之间移植的部分。 因此,调用便利过程 set_display_font 来隐藏内部并统一字体选择。 该过程是 HDevelop 标准过程路径的一部分,可以从任何程序中调用。

set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

程序的其余部分由一个 while 循环组成,只要按下鼠标右键,它就会终止。 鼠标操作符 get_mbutton 等待,直到用户用鼠标单击图形窗口,然后返回坐标和按钮值。 该坐标用于使用 select_region_point 选择包含该点的区域。 对于这个区域,大小和重心是用 area_center 计算的。 首先,使用 set_tposition 定位文本光标,并使用 write_string 显示值。 在这里,可以看出使用“+”运算符可以多么方便地组合字符串。

Button := 0 while (Button != 4) 
get_mbutton (WindowHandle, Row, Column, Button) 
select_region_point (Regions, DestRegions, Row, Column) 
area_center (DestRegions, Area, RowCenter, ColumnCenter) 
if (|Area| > 0)
    set_tposition (WindowHandle, Row, Column) 
    dev_set_color ('yellow') 
    write_string (WindowHandle, '(' + RowCenter + ', \
' + ColumnCenter + ') = ' + Area)
endif

Halcon之可视化_第6张图片
图 19.5:所选区域的重心和面积.

4、选择算子

4.1、处理图形窗口

Standard:
open_window, clear_window, close_window, set_window_param

4.2、显示

Standard:
set_paint, set_lut, set_part_style, set_draw, set_line_width, set_color, set_colored, disp_obj, set_font, set_tposition, write_string, unproject_coordinates, update_window_pose
Advanced:
disp_image, disp_color, disp_region, disp_xld

4.3、鼠标交互

Standard:
get_mposition, get_mposition_sub_pix, get_mbutton, get_mbutton_sub_pix, draw_region, draw_circle

4.4、Gnuplot

Advanced:
gnuplot_open_file, gnuplot_open_pipe, gnuplot_plot_ctrl, gnuplot_plot_image

5、提示与技巧

5.1、保存窗口内容

HALCON 提供了一种将图形窗口的内容保存到文件的简单方法。 例如,这可以用于文档目的。 相应的运算符称为 dump_window。 它以窗口句柄和文件名作为输入。 参数设备允许在不同的文件格式中进行选择。

5.2 执行时间处理时间

通常,可视化需要时间。为了减少时间,建议仅在特定任务确实需要时才进行可视化。使用 HDevEngine 时(请参阅第 7 部分第 207 页的程序员指南),默认情况下禁止执行所有 dev_* 运算符。因此,在使用 HDevelop 进行开发时,您可以根据需要使用尽可能多的显示运算符,但在从编程语言执行最终应用程序时可以节省时间。
对运行时间的进一步影响涉及显卡和位深度。在许多情况下,选择位深度 16 而不是 32 可以显着加快程序执行速度。因此,如果速度对您很重要,我们建议您简单地尝试不同的位深度,执行典型的显示运算符,如 disp_image、disp_color、disp_region 或 disp_xld,并使用 count_seconds 测量执行时间。此外,虽然它通常对运行时间的影响很小,但也存在一些情况,您也可以通过选择较低的屏幕分辨率来加速可视化。

6、高级主题

6.1、编程环境

图形窗口的处理在不同的编程环境中有所不同。特别是 HDevelop 有一种特定的可视化工作方式。
因为HDevelop 是一个交互式环境,所以窗口的处理必须尽可能简单。尤其重要的是,无需任何编程即可显示数据。因此,只有在需要时才使用窗口句柄的概念。通常,没有明确指定输出必须转到的窗口。相反,HDevelop 使用图形窗口的激活状态。因此,HDevelop 的显示操作符没有窗口句柄的参数。 HDevelop 中的可视化操作符看起来与 HALCON 的对应操作符相同,只是它们的名称以 dev_ 开头并且窗口句柄的参数被抑制。导出代码时,会自动插入这个缺失的句柄。
第二个区别是 HDevelop 中的窗口具有在调整窗口大小时自动重新显示数据的历史记录。标准 HALCON 图形窗口不是这种情况。
最后一个区别是 HDevelop 会根据当前图像自动设置坐标系,而在使用 HALCON 时,您必须使用编程代码显式执行此操作。为了使导出到例如 C++、C# 或 Visual Basic 透明,我们建议在处理多个图形窗口时使用 dev_set_window 并调用 dev_set_part 来指定坐标系
在 MFC 中使用 HALCON 窗口时,通常的方法是将窗口用作父窗体的子窗口。这可以通过使用当前窗体的窗口句柄作为父窗体来轻松实现。句柄必须转换为长值,然后可以传递给 open_window。请注意,在这种情况下,需要 set_check 来更改 HALCON 的异常处理。

set_window_attr("border_width", 0); 
set_check("~father"); 
long lWWindowID = (long)m_hWnd; 
open_window(0, 0, 640, 480, lWWindowID, "visible", "", &m_lWindowID); 
set_check("father");

在 Visual Basic 中打开 HALCON 窗口类似于用于 MFC 的方法。 在这里,您使用窗体或另一个子窗口(如图片框)的 memberhWnd。 作为替代,可以使用 HWindowXCtrl。

Call sys.SetCheck("~father")
Call op.OpenWindow(8, 8, 320, 240, form.hWnd, "", "", WindowHandle)
Call sys.SetCheck("father")

6.2、无闪烁可视化

对于无闪烁的可视化,顺序调用显示操作符是不合适的,因为每次调用后新数据会立即刷新在可见屏幕上,这可能会导致闪烁结果。
在 Linux/Mac OS X 下,或者如果您想创建一个独立于平台的应用程序,除了可见窗口之外,还可以通过使用缓冲区窗口来解决这个问题。使用 open_window 打开缓冲区窗口,同时将 Mode 设置为“buffer”。然后,所有绘图操作都在缓冲区窗口中执行。最后,使用 copy_rectangle 将缓冲区窗口内容复制到可见窗口中。在 hdevelop/Transformations/2D-Transformations/projective_trans_pixel.hdev 下提供了一个使用缓冲区窗口的示例。
专门使用 Windows 时,可以使用更快的方法。在这里,您可以调用 set_system 并将参数值 ‘flush_graphic’ 设置为 ‘false’,执行所有显示操作 - 除了最后一个 - 然后再次调用 set_system 并将 ‘flush_graphic’ 设置为 ‘true’。当最终应用显示序列的最后一个显示调用时,整个数据一步变得可见。在 solution_guide/basics/median_interactive.hdev 下提供了使用此方法的示例。

6.3、远程可视化

在某些应用中,用于处理的计算机不同于用于可视化的计算机。 可以使用 HALCON 使用套接字通信轻松创建此类应用程序。 send_image 或 receive_tuple 等运算符允许将相关数据透明传输到控制计算机以在那里应用可视化。

6.4、程序化可视化

有时可能不需要应用标准的 HALCON 可视化运算符,而是使用自编程版本。这可以通过使用为所有数据类型提供的访问函数来实现。
这些示例包括 get_image_pointer1、get_region_runs 或 get_contour_xld。像这样的运算符允许完全访问所有内部数据类型。此外,它们以各种形式(例如,游程编码、点或轮廓)提供数据,以使进一步处理更容易。基于这些数据,可以轻松开发自编程的可视化。
作为替代,可以使用 set_window_type 选择窗口类型“pixmap”。在这种情况下,所有显示的数据都被绘制到可以使用 get_window_pointer3 访问的内部缓冲区中。返回的指针引用缓冲区的三个颜色通道。然后可以轻松地传输该缓冲区(例如,到另一个系统)和/或转换为所需的格式。转换的一个示例是调用 gen_image3 以创建 HALCON 彩色图像。

你可能感兴趣的:(HALCON,linux,c#,windows)