Tuvimos la misma tarea en uno de nuestros proyectos.
Para obtener el modelo de fondo, simplemente creamos una clase BackgroundModel, capturamos el primer (digamos) 50 marcos y calculamos el marco promedio para evitar errores de píxeles en el modelo de fondo.
Por ejemplo, si obtiene una imagen en escala de grises de 8 bits (CV_8UC1) de su cámara, inicializa su modelo con CV_16UC1 para evitar el recorte.
cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0));
Ahora, a la espera de los primeros marcos para calcular el modelo, basta con añadir cada cuadro con el modelo y contar la cantidad de tramas recibidas.
void addFrame(cv::Mat frame) {
cv::Mat convertedFrame;
frame.convertTo(convertedFrame, CV_16UC1);
cv::add(convertedFrame, model, model);
if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50
createMask();
}
}
La función createMask() calcula el marco promedio que usamos para el modelo.
void createMask() {
cv::convertScaleAbs(model, mask, 1.0/learnedFrames);
mask.convertTo(mask, CV_8UC1);
}
Ahora, sólo envía todas las tramas del camino a través de la clase BackgroundModel a una función de resta(). Si el resultado es un cv :: Mat vacío, la máscara aún se calcula. De lo contrario, obtienes un marco restado.
cv::Mat subtract(cv::Mat frame) {
cv::Mat result;
if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50
cv::subtract(frame, mask, result);
}
else {
addFrame(frame);
}
return result;
}
Por último, pero no menos importante, puede utilizar suma escalar (const Mat & MTX) para calcular la suma de píxeles y decidir si se trata de un marco con las luces en él.
Muchas gracias ping (",) – user854576
@ user854576 Si esta es una respuesta correcta, debe ser amable y aceptarla. Consulte [esta página] (http://stackoverflow.com/faq#howtoask) en el Preguntas frecuentes sobre cómo aceptar respuestas. –