基本流程:
用到的算子(以及算子中的重要参数释义):
算子菜单的方式
算子
-Image
-read_image()
read_image (Image, 'printer_chip/printer_chip_01')
默认为读取一幅示例图像,支持多种图像格式,详见help

查询帮助可知,该算子可以从本地文件读取一幅图像到变量image中或者读取多张到变量images中,也可以设置搜索路径
* Reading an image:
read_image(Image,'mreut')
* Reading 3 images into an image array:
read_image(Images,['ic0','ic1','ic2'])
* Setting of search path for images on '/mnt/images' and '/home/images':
set_system('image_dir','/mnt/images:/home/images')快捷键
Ctrl+R打开一个读取图像的窗口,从中选择图像和设置变量(默认用图像文件名为变量名)


一个实例
read_image (Image, 'printer_chip/printer_chip_01')
read_image (Linux, 'C:/Users/Administrator/Pictures/Linux.png')
扩展与思考
如何将某目录下的所有图像读取到一个数组中,假设该目录下图像数量不固定
解析
利用采集助手批量读取文件夹下所有图像

代码生成——插入代码,如下:
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
endfor用到的算子有list_files,tuple_regexp_select,read_image
其中,list_files列出给定目录下的所有文件,放到ImageFiles变量中(这里files限制了只列出指定目录下的文件,而不递归列出子目录文件,详见帮助);tuple_regexp_select筛选符合条件的/指定格式的文件
参数ignore_case表示忽视大小写;|ImageFiles|表示数组长度;ImageFiles[Index]表示数组元素引用,下标从0开始;图像格式后面的美元符号$表示什么?
现象:即便目录下有多张图像,但是图像窗口和变量窗口只显示最后读取的一幅

变量监视窗口显示可读取的所有图像数量

实际我的目录下有如下图像

可见jtif格式未被读取,因为正则表达式过滤筛选时为(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj),没有jtif格式。
问题
如何将支持格式的所有图像全部用新窗口显示出来?【用助手可生成代码,当然也可以自己写】
通过查阅资料(教材),显示图像的步骤基本为:
关闭窗口/清除窗口(防止显示多余的图像出来,比如我没有清除/关闭打开的图像显示窗口,则执行时多显示一次已经打开的图像)
获取图像宽高(为了设置窗口大小用,那么如何新建一个根据图像大小自动调整大小的窗口呢?用dev_resize_window_fit_image(Image,0,0,-1,-1)或者dev_resize_window_fit_size(0,0,Width,Height,-1,-1)均可)
从算子的参数列表可知,dev_resize_window_fit_size(0,0,Width,Height,-1,-1)是按照Width,Height这两个参数调整窗口大小,而dev_resize_window_fit_image(Image,0,0,-1,-1)则是按照图像自身大小调整窗口大小,且后者不需要提前获取图像的高和宽!
新建一个窗口
显示图像
将上述步骤放在循环读取图像的for循环中即可,代码如下:
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
* dev_resize_window_fit_image (Image, 0, 0, -1, -1)
* disp_image()
dev_display(Image)
endfor运行结果如下

改进代码,意图去除重复图像
第一次测试发现最后一张图像还是显示2次<虽然很帅,但是很烦☺>(已经确认目录下只有一张该图片,不存在不同名的相同图像):
dev_close_window()
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
* dev_resize_window_fit_image (Image, 0, 0, -1, -1)
* disp_image()
dev_display(Image)
endfor
F2全部关闭并清空变量后
第二次测试:

怀疑是否倒数第三行的那个绿色代码作祟?测试发现,显然不是!(我太天真了~~~)——语法正确的算子被注释后为灰色,文字附加注释则默认为绿色,这里的disp_image()虽然是算子,但是不完整,被认为是一般文字注解了,所以是绿色。
* dev_close_window()
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
* dev_resize_window_fit_image (Image, 0, 0, -1, -1)
dev_clear_window ()
dev_display(Image)
endfor与中文名肯定无关!总之现在的问题就是最后一张图像会被重复显示,而且显示的窗口大小还不一样,问题肯定出在循环语句上?【后面发现不是!而是出在新建窗口语句的位置上,应该先新建窗口并清空内容,再read图像,自适应窗口大小后显示图像】

继续修正
增加stop()跟踪(相当于F9,停止后可按F5继续执行)
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
dev_display(Image)
stop()
endfor发现问题了:每一张图像都会出现两个显示窗口

第二个循环,发现170句柄未变,350句柄图像被更新,同时出现新的窗口2C0,而且新窗口2C0才是实际大小。

第三次循环,2C0倍更新,但是显示的图像大小被原2C0大小所限,新窗口句柄1D0为正常大小

第四次,不出意外的1D0 被更新,新窗口句柄290

第五次,290被更新,新窗口200为正常大小

现在的效果是这样:

第一幅那个企鹅被固定在了左上角图像窗口中,因为是第一个窗口(默认位置就是这里),没有问题!
现在的问题可以总结为:每一次循环,都会用新图像填充一次原窗口,然后再打开新窗口并用新图像填充,而且原窗口尺寸明显不对!这从第一幅企鹅图像和最后一幅图像可以看出来,也就是说原窗口应该销毁掉!
而关闭窗口的语句应该放在循环前还是后?从第一幅企鹅图像重复显示的尺寸关系看,应该放在循环体内,图像显示之前,测试如下:
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
dev_close_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
dev_display(Image)
stop()
endfor发现问题依然存在,而且只显示新图像了!~~~~无论如何努力都没有实现关闭原窗口!因为即便只是read_image (Image, ImageFiles[Index])也会在默认图形窗口显示
如果只是关闭多余窗口,可以通过循环结束后,关闭最后一个多余窗口即可,代码如下,但是,这样显示的图像尺寸都变形了,不是原始比例!
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
* dev_close_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
dev_display(Image)
stop()
*dev_close_window()
endfor
dev_close_window()所以,解决途径两种:
其一:继续执着于关闭原始窗口(这是最完美的,但是尚未实现);【或许可以先打开窗口,再read图像呢?应该可行,只是也要考虑窗口自适应图像大小的问题——测试发现的确可行】
其二(先实现的):关闭新窗口,并调整窗口自适应图像大小(也可行)
其三:其他方法(最优的方法,无闪烁,无重叠窗口,代码简单)
其一
*dev_close_window()
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
* dev_close_window()
dev_open_window(0,0,50,50,'white',WindowHandle)
dev_clear_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
*dev_open_window(0,0,Width,Height,'white',WindowHandle)
*dev_display(Image)
*dev_resize_window_fit_image(Image,0,0,-1,-1)
dev_resize_window_fit_size(0,0,Width,Height,-1,-1)
dev_display(Image)
*stop()
*dev_close_window()
endfor
*dev_close_window()或者
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
dev_open_window(0,0,50,50,'white',WindowHandle)
dev_clear_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
dev_resize_window_fit_image(Image,0,0,-1,-1)
dev_display(Image)
endfor
新问题
窗口调整大小时会闪烁(会看到填充了的图像大小变化的切换动画),怎么改进?【见下文的“其三”】
思路1:使调整的过程不可见,比如初始窗口尺寸设置为1像素(不可行)
思路2:
其二
*dev_close_window()
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
* dev_close_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
dev_display(Image)
dev_resize_window_fit_image(Image,0,0,-1,-1)
stop()
*dev_close_window()
endfor
dev_close_window()

发现新问题
1、新图像在原窗口填充时,只是覆盖原图像,当后面图像较小时出现上图中图像重叠的问题,所以需要先清空原窗口【因为read图像,就会直接read到原窗口中】
2、新图像小则填不满,新图像大则显示不完全!
原因:算子使用错误了!如果要求窗口自适应图像大小,显然算子中应该是用到图像的高、宽两个变量才对!所以应该用dev_resize_window_fit_size(0,0,Width,Height,-1,-1)
实测发现老样子!要哭了
或许应该先调整窗口大小,再显示图像?——【的确如此,但是read读入图像就会填入上一个窗口了,所以需要先清空再填充,而且,填入后就要调整窗口大小,然后再新建一个空窗口】
如下代码会显示不全,比例失调
*dev_close_window()
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
*dev_close_window()
dev_clear_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
*dev_clear_window()
*dev_display(Image)
*dev_resize_window_fit_image(Image,0,0,-1,-1)
dev_resize_window_fit_size(0,0,Width,Height,-1,-1)
dev_display(Image)
*stop()
*dev_close_window()
endfor
dev_close_window()改进如下
*dev_close_window()
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
*dev_close_window()
dev_clear_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_resize_window_fit_size(0,0,Width,Height,-1,-1)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
*dev_clear_window()
*dev_display(Image)
*dev_resize_window_fit_image(Image,0,0,-1,-1)
*dev_resize_window_fit_size(0,0,Width,Height,-1,-1)
*dev_display(Image)
*stop()
*dev_close_window()
endfor
dev_close_window()
精简后
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
dev_clear_window()
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_resize_window_fit_size(0,0,Width,Height,-1,-1)
dev_open_window(0,0,100,100,'white',WindowHandle)
endfor
dev_close_window()最后会新建一个空白窗口,循环结束后关闭该空白窗口,这两种方法本质上类似于while与do..while的区别了,但是其二方法中没有明显的窗口闪烁!(因为利用了默认的左上角的图形窗口了吗?该图形窗口被设置为了“适应窗口,保持高宽比例”)

其三
冥冥之中,总感觉有更好的解决办法,所以针对上面出现的认为不正常的现象(read就读取到图形窗口,冥冥之中感觉应该是可以改变的)百度了一下,果然~~~
http://www.skcircle.com/?id=1374 中提到:

所以,按照这个方法,取消read后就显示图像,菜单“可视化”——“更新窗口”,取消“在运行模式”前面的√(默认是勾选的),然后选择“在单步模式”下一级的“从不”或者“清空并显示”以关闭窗口更新
也可以调用dev_update_window('off')关闭窗口的更新,关闭窗口更新后,只能用dev_display()来显示图像


代码如下
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Administrator/Pictures', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
get_image_size(Image,Width,Height)
dev_open_window(0,0,Width,Height,'white',WindowHandle)
dev_display(Image)
endfor
提示:帮助文件中要复制内容,不能用键盘的Ctrl+C,需要用鼠标!
另外,发现的问题:程序执行一次后,再次运行会没有反应,需要
F2重置程序执行(F2后发现所有变量被清空了,那么用代码怎么实现“重置程序执行”?)
More information about visualization in general can be found in the Solution Guide I. Note that in this manual, the HDevelop version of the display operators is used, i.e., with the prefix dev_, e.g., dev_open_window instead of OpenWindow.
All operators in this menu start with the prefix dev_. It has been introduced to have a distinction to the underlying basic HALCON operators (e.g., dev_set_color and set_color).
比如dev_display(Image)和disp_image()的区别:前者可现实彩色图像(gif不能显示动画,只显示第一帧),后者只能显示灰度图像
那么问题又来了:如何显示gif动画?
dev_clear_window ()和dev_close_window (),前者清除激活窗口的内容,但是窗口依然激活状态(句柄仍可用),后者关闭窗口(杀死句柄)
批量注释:选中代码段,右键,注销
取消注释:选中注释掉的代码段,右键,激活