LabVIEW HALCON图像处理入门教程-动态调用和静态调用

[复制链接]
查看34623 | 回复0 | 2024-5-10 14:51:15 | 显示全部楼层 |阅读模式
DLL动态库中的函数调用分为动态调用和静态调用。首先需要明白动态调用和静态调用的概念和区别。动态调用和静态调用的概念在LabVIEW中是不太一样的,或者说LabVIEW中说的动态调用和静态调用,并不是指DLL中的动态库中的函数的调用方式,而是指LabVIEW调用子VI的方式。LabVIEW静态调用是指打开主程序时,子VI也同时被装载到内存中;而动态调用,则是打开主程序时,子VI不装载到内存中,只是在有需要的时候再装载到内存中。动态调用的方式,可以加快大型软件的启动速度。当然,对于一些小程序,其实静态调用更方便。当然对于DLL中的函数的实现,其实和LabVIEW中也是差不多的意思,也是分为动态调用和静态调用的,静态的先分配内存,动态的是在调用过程中分配内存,不同的函数调用类型,需要处理的方式是不一样的。

那么LabVIEW在调用这些函数时,处理的方法也是不一样的,静态调用时,先分配内存,程序在整个运行过程中,新、旧数据(例如图像,上帧、下帧图像)都是使用同一内存地址,新数据是覆盖旧数据的,这时就不会因为程序在连续循环运行时,而创建太多的数据副本导致内存越来越大,可以在程序退出时释放静态调用占用的内存即可(或不释放由软件自动处理也可以)。而动态调用,则是在运行过程中,每次调用时动态创建内存,新、旧数据放在不同的内存地址中,如果数据处理过后,不及时销毁,则会造成占用内存越来越大最终导致溢出的问题。这时,就需要在处理完数据后,及时销售数据,释放其占用的内存,这样才能保证程序在连续循环运行时,不会导致内存溢出。

LabVIEW通过.NET调用Halcon的DLL库时,同样会遇到这样的问题。如果调用的是DLL中的动态函数,那么请注意处理完成后,及时释放其占用的内存资源以及关闭.NET调用引用。而如果调用的是DLL中的静态函数,则可以在程序最后再释放内存资源和关闭调用引用。

如果对于动态调用和静态调用的意义不是太明白,那么可以简单的来说一下变量的作用范围大概就可以明白其方式了,静态调用时,变量作用整个程序运行过程,在LabVIEW中,你可以认为是LabVIEW的While循环外的变量;而动态调用时,变量是在中间过程中创建的,可以认为是LabVIEW的While循环内的变量。如下图所示的一种图像采集过程:



LabVIEW动态分配内存采集图像

上面的这个小示例,就是在While内部动态的创建了内存地址用于存储图像,每个图像的内存引用使用了While的循环计数来命名,循环多少次,就会创建多少内存。运行一段时间会,LabVIEW就会占用大量的内存,直到最后崩溃。



LabVIEW占用内存很快超1G

当然,在动态分配内存采集图像时,也可以使用相同的名称分配内存地址:



LabVIEW动态分配相同名称的图像内存

但是这样直接运行时,图像是显示不出来的,可以使用高亮来看一下,倒是可以显示图像,因为在后面的重新分配过程中,还有一定的时间:



LabVIEW动态分配相同名称的图像内存-高亮显示

这种方式是不推荐的,从前面的连续运行时可以看到,根本来不及显示图像,就会被新的数据覆盖掉,而导致无法显示图像。当然,对于图像处理过程中,一些中间过程的过渡图像,前后必然有一定的时间间隔的,那么其实使用这种方式也是可以的,例如一些中间的二值化过程。LabVIEW官方的一些示例也是这样处理的。

无论是前面的那种不同名称的方式,还是后面这种相同名称的方式,都是需要在While中处理完成相应的内容时,释放掉图像占用的内存资源的。而不是将释放函数放在While循环外面,程序退出时才释放,这才是一个正常的动态分配内存的标准过程:



LabVIEW动态分配图像内存-标准过程

但是这样也是无法正常显示,因为后面的销毁内存过程太快,来不及显示,如果使用高亮显示,则可以正常显示:



动态分配内存的标准过程-高亮显示

高亮显示时可以显示图像,内存也没有增加,是一个准确的可用的方式。



LabVIEW静态分配相同名称的图像内存

而如果将创建函数放到While循环外面去,则整个While循环将直接使用已经创建的内存地址引用,这时就是一个明显的静态变量过程。这时在While过程中,一直都是使用初始化时创建的内存地址,也不会在运行过程再去创建内存。在这种方式中,While内是不需要去释放内存资源的。释放了反而就没有相应的内存资源了,而导致后续的循环错误。只需要在程序退出时释放一下,或者不处理,由LabVIEW自动释放内存也是可以的。

LabVIEW调用Halcon中的函数时,因为Halcon中的同样的函数功能,会包含在很多不同的库中,所以要看您具体调用的是哪个库。如果是[S]开头的函数,那么就属于静态调用的函数,在中间过程中,可以不释放资源;而如果不是[S]开头的,那就是动态函数,需要在在调用完成后,释放掉所有占用的资源以及引用。



[S]开头的静态函数



非[S]开头的动态函数

Halcon中的库函数,HOperatorSet类中的函数,都是静态函数;而其他类中的函数,大部分都是动态函数,只有少部分是静态函数,还请调用时注意其函数类型。



调用静态函数求图像的均值和偏差



调用动态函数求图像的均值和偏差

关于LabVIEW调用Halcon函数的动态调用和静态调用的更多内容,请观看视频号解释视频:

LabVIEWHALCON图像处理入门教程-动态调用和静态调用视频解说

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则