1 读取图片需要及时手动释放
一个6M的图片通过halcon进行加载,大约会消耗200M的内存,如果等待GC回收,而你又在不停的读取图片,你的内存占用,将在短时间内飙升。
2 halcon控件显示图片需要清空。
/// <summary>
/// 显示对象
/// </summary>
/// <param name="obj"></param>
/// <param name="bFull"></param>
public void ShowObj(HObject obj, bool bFull = true)
{
hSmart?.HalconWindow.ClearWindow(); //必须清理掉不然会显示多张图片
hSmart?.HalconWindow.DispObj(obj);
if (bFull)
{
hSmart?.SetFullImagePart();
}
}
在显示前清空窗口,不然会覆盖显示多张图片,从而使得内存一路上涨。
3 先opening再打散
通过connection算子打散区域之前,先看看得到多少个区域,如果单个区域过多也会占用大量内存,毕竟打散之前是一个对象,打散之后可能是几万个对象。
所以,可以先对整体进行opening操作,去掉一些小杂碎,再打散就会得到更少的对象,从而减少内存的压力
4 高消耗算子
目前我遇到了两个能大量消耗内存算子,图片越大消耗的内存几乎成指数上升。
- edges_sub_pix 这个函数用于找边缘非常好用,但是如果你直接对一个6M图片进行全图操作,一瞬间你可能就会消耗3个G的内存! 所以,好的做法是先通过blob进行定位,然后抠图。然后对图的局部进行edges_sub_pix,此时内存压力会小很多。
- lines_gauss 这个函数用于找划痕之类的瑕疵非常好用,缺点也是计算量太大,会消耗大量的内存。但是这个函数和edges_sub_pix 还不一样。因为如果你是找划痕一般就是针对全图的,没有抠图的余地,所以如果图片很大,内存飙升就是板上钉钉。
5 halcon引擎中使用高消耗算子
我们知道使用halcon引擎是我们开放变得非常方便,但是如果在halcon引擎中使用高消耗算子,这点是非常致命的。比如在halcon引擎lines_gauss此时内存会飙升,更惨的是释放的还慢。如果不使用halcon引擎,直接调用lines_gauss虽然内存会飙升,但是属于图片占用的内存还是会立刻被释放,但是如果在halcon引擎中,这个就会释放很慢,如果连续处理图片,你的内存就会“爆炸”!多的部分会溢出到硬盘,你的硬盘读写就会飙升,然后你的电脑就卡了。
6 halcon引擎中传入图片
目前给我的感觉是,如果我封装了一个算子,然后通过halcon引擎调用,然后这个算子需要传入图片参数,这个图片传入引擎后,过很久才会被释放掉。
7 unin 输入输出(待验证)
Union2的出参和入参一致时,必须手动释放,这样才能100% 马上回收内存。
貌似大家都用遇到过这种问题,当入参和出参相同时,可能会造成内存释放缓慢。我目前还没明显体会到,有待以后验证!
8 对轮廓进行合并
如果此时有很多细小的轮廓(几千个几万个),此时将会非常耗时。
小结
当halcon用到一个算子,消耗了3个G的内存,如果这个消耗的内存是,算子本身需要分配的内存,那么此时这片内存一般不会被释放,会一直保留在那。我感觉这是halcon的一种提升速度策略。但如果是图片加载导致的内存上升,这种一般很快就会被回收掉。
貌似,可以通过halcon提供的函数,改变这种策略,以避免内存的大量消耗,等我搞明白了再和大家分享。