Software para detección y parametrización de objetos.
Sustraccion de fondo o Background subtraction en OpenCV
Para mejorar las posibilidades de la detección de cuadrados en busca de la carátula de CD me he aventurado a probar la sustracción de fondo.
Considero que la cámara va a estar colocada en un sitio concreto. Incluso me estoy planteando enfocarla hacia arriba. Pero eso es facilitarme las cosas demasiado. Primero quiero ver las carátulas y después ir subiendo la complejidad. Es posible que cada vez que suba un nivel de complejidad el enfoque para llegar a la solución sea diferente. Pero lo importante es aprender
Acepto críticas y sugerencias. (De sabios es evaluar y dudar cuidadosamente cualquier afirmación).
Con este enfoque pretendo quedarme con lo que se mueva y a partir de ahí pasar el detector de cuadrados.
En el código que estoy utilizando:
- Es un refrito, hay partes en castellano y otras en ingles. ¡ Son pruebas !
- Se está realizando una sustracción del fondo Gausiana (Gaussian Mixture Model)
- Se genera un mapa de bits donde el negro absoluto significa fondo y el blanco puro significa “no fondo” ( es decir, algo en movimiento)
- En la ventana llamada “Original” genero una imagen en la que solo se ve lo que está en movimiento.
- Tiene un warning en la asignación de valor a x, insisto! son pruebas!
Enlaces de interés:
- Proyecto fin de carrera que lo utiliza y me gusta la idea: “PFC – URJC – Detector de objetos abandonados“
- Background Subtraction
- Mixed Models (Gaussian Mixture Model)
- Código fuente original
Código:
#include "cv.h"
#include "cvaux.h"
#include "highgui.h"
#include <stdio.h>
const CvScalar C_RGB_BLACK = cvScalar(0,0,0);
const CvScalar C_RGB_WHITE = cvScalar(255,255,255);
const CvScalar C_GRAY_WHITE = cvScalar(255);
const CvScalar C_GRAY_BLACK= cvScalar(0);
const CvScalar C_RGB_RED = cvScalar(0,0,255);
void paintPixel(IplImage* in,int x, int y,CvScalar color) throw()
{ // comprueba que los puntos están dentro de la imagen
if(in != NULL)
{
if(y>=0 && y<(in->height) && x>=0 && x<(in->width))
{ // modifica el pixel a nivel de byte sobre el vector de la imagen.
char *data = in->imageData;
data[y*in->widthStep+x*in->nChannels]=color.val[0];
data[y*in->widthStep+x*in->nChannels+1]=color.val[1];
data[y*in->widthStep+x*in->nChannels+2]=color.val[2];
}
}
}
// TODO
bool comparePixel(IplImage* in,int x, int y,CvScalar color) throw()
{ // comprueba que los puntos están dentro de la imagen
if(in != NULL)
{
char *data = in->imageData;
return(data[y*in->widthStep+x*in->nChannels]==color.val[0]);
}
return false;
}
//this is a sample for foreground detection functions
int main(int argc, char** argv)
{
IplImage* tmp_frame = NULL;
CvCapture* cap = NULL;
cap = cvCreateCameraCapture(0);
tmp_frame = cvQueryFrame(cap);
if(!tmp_frame)
{
printf("bad video \n");
exit(0);
}
cvNamedWindow("BG", 1);
cvNamedWindow("FG", 1);
cvNamedWindow("Original", 1);
//create BG model
CvBGStatModel* bg_model = cvCreateGaussianBGModel( tmp_frame );
double t;
IplImage* cpy;
int x = 0;
int y = 0;
for( int fr = 1;tmp_frame; tmp_frame = cvQueryFrame(cap), fr++ )
{
t = (double) cvGetTickCount();
// Background substraction
cvUpdateBGStatModel( tmp_frame, bg_model );
cpy = cvCloneImage( bg_model->foreground );
for (x=(cpy->width-1);x>=0;x=x--)
for (y=(cpy->height-1);y>= 0;y--)
if(comparePixel(cpy,x,y,C_GRAY_BLACK))
paintPixel(tmp_frame,x,y,C_RGB_BLACK);
cvShowImage("BG", bg_model->background);
cvShowImage("FG", bg_model->foreground);
cvShowImage("Original", tmp_frame);
int k = cvWaitKey(15);
if( k == 27 ) break;
//printf("frame# %d \r", fr);
}
cvReleaseBGStatModel( &bg_model );
cvReleaseCapture(&cap);
return 0;
}





February 17, 2010 - 9:53 am
Cuidado con la terminología:
“Se genera un mapa de bits donde el negro absoluto significa fondo y el blanco puro significa “no fondo” ( es decir, algo en movimiento)”
la sustracción de fondo simplemente elimina los niveles de intensidad que considera como fondo a cada fotograma. Hay muchos métodos, adaptativos o no, pero no muestra lo que se mueve, sino lo que es diferente de lo que ha considerado como fondo, esté, o no, en movimiento. Es decir, que en lugar de hablar de “detección de movimiento”, hay que hablar de “detección de presencia”.
Respecto al hecho de localizar “cuadrados”, lo mejor es parametrizar qué es un cuadrado y buscarlos a través de múltiples medidas (filtrado de bordes, detector de presencia, detector de movimiento,…) cuantas más medidas de detección de cuadrados puedas tener correlacionadas, mejor será tu detector. De hecho, la visión humana utiliza muchas medidas de forma natural, si por niveles de intensidad nos da sensación de cuadrado, en seguida utilizamos más medidas (de profundidad, de relieve,…) para llegar a identificar que el cuadrado es un CD y no es una pintura en la pared o superficie. A ver si te da pistas….
Ánimo!
February 17, 2010 - 10:19 am
Ok Antonio, muchas gracias! en cuanto pueda modifico la entrada.
En cierto modo por eso voy preguntando, soy todavía un poco nuevo en lo que a vision se refiere. Gracias!
March 14, 2010 - 3:50 am
Buenas muchachos, necesito de su sapienza para dar en el clavo con un problemilla de reconocimiento de objetos.
Tengo una imagen con dos objetos idénticos (igual color, forma y tamaño) pero son dos objetos distintos excepto que cada uno puede o no tener una “marca” diferente de la marca del otro.
Lo que necesito es separar esos objetos del fondo y además separarlos a cada uno, de manera de poder reconocer la marca que posee y determinar a qué objeto pertenece dicha marca.
No sé si se entiende el problema. Si lograron entenderlo ¿pueden tirarme alguna pista sobre alguna posible solución? Actualmente utilizo OpenCV y C++ sobre Linux.
Saludos y Muchas Gracias!
June 14, 2013 - 8:23 am
As the pretty welding machines made available to welders, which the welding fly fishing line cookware 3 .
called 1 electrode your oven, hot and spicy device welding electrode stabilizing tandoor : might be
lustrous and as a result redesigned gradually if you need to cater for welders that many within different types of tedious environment.
Put together a meal them until finally finally they start to ease.
Combine it with the actual flour solution near the peanuts and can then be stir
these kinds of in the future closely. 2nd is definitely the heating element.
Allow to pleasure for 20 temps, in readiness all of the other food items.