Pregunta Detección de la cara asíncrona de Golang


Estoy usando un Biblioteca de enlace OpenCV para Go y tratando de detectar asincrónicamente objetos en 10 imágenes, pero sigues recibiendo este pánico. La detección de solo 4 imágenes nunca falla.

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()

Soy bastante nuevo en OpenCV y Go y trato de entender dónde está el problema. Supongo que se está agotando algún recurso, pero cuál.


11
2017-09-10 21:49


origen


Respuestas:


Cada vez que llamas a DetectObjects, la implementación subyacente de OpenCV construye un árbol de clasificadores y los almacena dentro de cascade. Puede ver parte del manejo de estos fragmentos de memoria en https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/haar.cpp línea 2002

Tu código original solo tenía una cascada como global. Cada nueva llamada de rutina DetectObjects utilizó la misma cascada de raíz. Cada nueva imagen habría liberado la memoria anterior y reconstruido un nuevo árbol y eventualmente pisarían el uso de la memoria del otro y causarían una desreferencia de 0, causando el pánico.

Mover la asignación de la cascada dentro de la goroutine asigna una nueva para cada DetectObject llamar y no comparten ninguna memoria.

El hecho de que nunca sucedió en 4 imágenes, pero falló en 5 imágenes es la naturaleza de la informática. Tuviste suerte con 4 imágenes y nunca viste el problema. Siempre vio el problema en 5 imágenes porque exactamente lo mismo sucedía cada vez (independientemente de la concurrencia).

Repetir la misma imagen varias veces no hace que el árbol en cascada se reconstruya. Si la imagen no cambió, ¿por qué hacer el trabajo ... una optimización en OpenCV para manejar múltiples marcos de imágenes.


11
2017-09-14 17:35



El problema parecía ser tener la cascada como una variable global.

Una vez que me mudé
cascade := opencv.LoadHaarClassifierCascade("haarcascade_frontalface_alt.xml")
en el goroutine todo estaba bien.


4
2017-09-14 15:01



Usted no está manejando por un cero image

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

2
2017-09-11 21:24