我正在使用一个
OpenCV binding library for Go,并尝试异步检测10个图像中的对象,但不断获得
this panic.只检测4个图像永远不会失败.
var wg sync.WaitGroup for j := 0; j < 10; j++ { wg.Add(1) go func(i int) { image := opencv.LoadImage(strconv.Itoa(i) + ".jpg") defer image.Release() faces := cascade.DetectObjects(image) fmt.Println((len(faces) > 0)) wg.Done() }(j) } wg.Wait()
我对OpenCV和Go来说是相当新鲜的,并试图弄清楚问题所在.我猜测有些资源正在耗尽,但哪一个资源正在耗尽.
每次调用DetectObject时,OpenCV的底层实现都会构建一个分类树,并将它们存储在级联中.您可以在2002年
https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/haar.cpp线看到处理这些内存块的部分内容
您的原始代码只有一个级联作为全局.每个新的go例程调用DetectObjects使用相同的根级联.每个新图像都会释放旧的内存并重建一个新的树,最终他们会踩踏对方的内存使用,并通过0导致重新引用,引起恐慌.
在goroutine内移动级联的分配为每个DetectObject调用分配一个新的级别,并且它们不共享任何内存.
事实上,它从来没有发生在4个图像上,但在5个图像上失败是计算的本质.你有4张图像很幸运,从未看到这个问题.你总是看到5个图像上的问题,因为每次都发生了同样的事情(不管并发).
重复相同的图像多次不会导致级联树被重建.如果图像没有改变为什么要做的工作…在OpenCV中处理多个图像框架的优化.