Golang异步人脸检测

时间:2014-09-10 21:49:17

标签: opencv asynchronous go

我正在使用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的新手,并试图找出问题所在。我猜测有些资源正在耗尽但是哪一个。

3 个答案:

答案 0 :(得分:13)

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

看到处理这些内存块的部分内容

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

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

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

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

答案 1 :(得分:4)

问题似乎是将级联作为全局变量。

一旦我搬了 cascade := opencv.LoadHaarClassifierCascade("haarcascade_frontalface_alt.xml")
进入goroutine一切都很好。

答案 2 :(得分:2)

您没有处理零image

image := opencv.LoadImage(strconv.Itoa(i) + ".jpg")
if image == nil {
    // handle error
}