石鑫华视觉论坛

 找回密码
 注册会员
查看: 279|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    半小时前
  • 签到天数: 3387 天

    连续签到: 9 天

    [LV.Master]2000FPS

     楼主| 发表于 2024-2-18 12:30:10 | 显示全部楼层 |阅读模式 来自:广东省东莞市 电信

    注册登陆后可查看附件和大图,以及购买相关内容

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

    x
    LabVIEW HALCON图像处理入门教程-动态调用和静态调用
             DLL动态库中的函数调用分为动态调用和静态调用。首先需要明白动态调用和静态调用的概念和区别。动态调用和静态调用的概念在LabVIEW中是不太一样的,或者说LabVIEW中说的动态调用和静态调用,并不是指DLL中的动态库中的函数的调用方式,而是指LabVIEW调用子VI的方式。LabVIEW静态调用是指打开主程序时,子VI也同时被装载到内存中;而动态调用,则是打开主程序时,子VI不装载到内存中,只是在有需要的时候再装载到内存中。动态调用的方式,可以加快大型软件的启动速度。当然,对于一些小程序,其实静态调用更方便。当然对于DLL中的函数的实现,其实和LabVIEW中也是差不多的意思,也是分为动态调用和静态调用的,静态的先分配内存,动态的是在调用过程中分配内存,不同的函数调用类型,需要处理的方式是不一样的。
    那么LabVIEW在调用这些函数时,处理的方法也是不一样的,静态调用时,先分配内存,程序在整个运行过程中,新、旧数据(例如图像,上帧、下帧图像)都是使用同一内存地址,新数据是覆盖旧数据的,这时就不会因为程序在连续循环运行时,而创建太多的数据副本导致内存越来越大,可以在程序退出时释放静态调用占用的内存即可(或不释放由软件自动处理也可以)。而动态调用,则是在运行过程中,每次调用时动态创建内存,新、旧数据放在不同的内存地址中,如果数据处理过后,不及时销毁,则会造成占用内存越来越大最终导致溢出的问题。这时,就需要在处理完数据后,及时销售数据,释放其占用的内存,这样才能保证程序在连续循环运行时,不会导致内存溢出。
    LabVIEW通过.NET调用Halcon的DLL库时,同样会遇到这样的问题。如果调用的是DLL中的动态函数,那么请注意处理完成后,及时释放其占用的内存资源以及关闭.NET调用引用。而如果调用的是DLL中的静态函数,则可以在程序最后再释放内存资源和关闭调用引用。
    如果对于动态调用和静态调用的意义不是太明白,那么可以简单的来说一下变量的作用范围大概就可以明白其方式了,静态调用时,变量作用整个程序运行过程,在LabVIEW中,你可以认为是LabVIEW的While循环外的变量;而动态调用时,变量是在中间过程中创建的,可以认为是LabVIEW的While循环内的变量。如下图所示的一种图像采集过程:
    image1.png
    LabVIEW动态分配内存采集图像
             上面的这个小示例,就是在While内部动态的创建了内存地址用于存储图像,每个图像的内存引用使用了While的循环计数来命名,循环多少次,就会创建多少内存。运行一段时间会,LabVIEW就会占用大量的内存,直到最后崩溃。
    image2.png
    LabVIEW占用内存很快超1G
             当然,在动态分配内存采集图像时,也可以使用相同的名称分配内存地址:
    image3.png
    LabVIEW动态分配相同名称的图像内存
             但是这样直接运行时,图像是显示不出来的,可以使用高亮来看一下,倒是可以显示图像,因为在后面的重新分配过程中,还有一定的时间:
    image4.png
    LabVIEW动态分配相同名称的图像内存-高亮显示
             这种方式是不推荐的,从前面的连续运行时可以看到,根本来不及显示图像,就会被新的数据覆盖掉,而导致无法显示图像。当然,对于图像处理过程中,一些中间过程的过渡图像,前后必然有一定的时间间隔的,那么其实使用这种方式也是可以的,例如一些中间的二值化过程。LabVIEW官方的一些示例也是这样处理的。
             无论是前面的那种不同名称的方式,还是后面这种相同名称的方式,都是需要在While中处理完成相应的内容时,释放掉图像占用的内存资源的。而不是将释放函数放在While循环外面,程序退出时才释放,这才是一个正常的动态分配内存的标准过程:
    image5.png
    LabVIEW动态分配图像内存-标准过程
             但是这样也是无法正常显示,因为后面的销毁内存过程太快,来不及显示,如果使用高亮显示,则可以正常显示:
    image6.png
    动态分配内存的标准过程-高亮显示
             高亮显示时可以显示图像,内存也没有增加,是一个准确的可用的方式。
    image7.png
    LabVIEW静态分配相同名称的图像内存
             而如果将创建函数放到While循环外面去,则整个While循环将直接使用已经创建的内存地址引用,这时就是一个明显的静态变量过程。这时在While过程中,一直都是使用初始化时创建的内存地址,也不会在运行过程再去创建内存。在这种方式中,While内是不需要去释放内存资源的。释放了反而就没有相应的内存资源了,而导致后续的循环错误。只需要在程序退出时释放一下,或者不处理,由LabVIEW自动释放内存也是可以的。
             LabVIEW调用Halcon中的函数时,因为Halcon中的同样的函数功能,会包含在很多不同的库中,所以要看您具体调用的是哪个库。如果是[S]开头的函数,那么就属于静态调用的函数,在中间过程中,可以不释放资源;而如果不是[S]开头的,那就是动态函数,需要在在调用完成后,释放掉所有占用的资源以及引用。
    image8.png
    [S]开头的静态函数
    image9.png
    [S]开头的动态函数
             Halcon中的库函数,HOperatorSet类中的函数,都是静态函数;而其他类中的函数,大部分都是动态函数,只有少部分是静态函数,还请调用时注意其函数类型。
    image10.png
    调用静态函数求图像的均值和偏差
    image11.png
    调用动态函数求图像的均值和偏差
             关于LabVIEW调用Halcon函数的动态调用和静态调用的更多内容,请观看视频号解释视频:
              image12.png
    LabVIEWHALCON图像处理入门教程-动态调用和静态调用视频解说

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册会员

    本版积分规则

    LabVIEW HALCON图像处理入门教程(24.09)
    石鑫华机器视觉与LabVIEW Vision图像处理PDF+视频教程11种全套
    《LabVIEW Vision函数实例详解2020-2024》教程-NI Vision所有函数使用方法介绍,基于NI VISION2020,兼容VDM21/22/23/24

    QQ|石鑫华视觉论坛 |网站地图

    GMT+8, 2024-11-25 08:27

    Powered by Discuz! X3.4

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表