Golang异步人脸检测

bra*_*ley 12 opencv asynchronous go

我正在为Go使用一个OpenCV绑定库,并试图异步检测10个图像中的对象,但不断发生这种恐慌.仅检测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()
Run Code Online (Sandbox Code Playgroud)

我是OpenCV和Go的新手,并试图找出问题所在.我猜一些资源正在耗尽,但哪一个.

And*_*ewN 13

每次调用DetectObjects时,OpenCV的底层实现都会构建一个分类器树并将它们存储在其中cascade.你可以在https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/haar.cpp line 2002 看到这些内存处理的一部分.

您的原始代码只有一个级联作为全局.每个新的go例程调用都DetectObjects使用相同的根级联.每个新图像都会释放旧内存并重新构建一个新树,最终它们会踩踏彼此的内存使用并导致取消引用0,从而导致恐慌.

在goroutine中移动级联的分配为每个DetectObject调用分配一个新的,并且它们不共享任何内存.

它从未发生在4幅图像上,但在5幅图像上失败的事实是计算的本质.幸运的是有4张图片,从未见过这个问题.你总是在5个图像上看到问题,因为每次都发生了完全相同的事情(无论并发性).

多次重复相同的图像不会导致重建级联树.如果图像没有改变,为什么要工作......在OpenCV中优化处理多个图像帧.