jueves, 29 de mayo de 2014

Otra de las aplicaciones muy practicas que podemos crear con opencv es un sistema de detección de movimientos, podremos por ejemplo usar una webcam para detectar movimiento y hacer que se una notificación a nuestro teléfono, las aplicaciones son muchas por lo que en este tutorial nos iniciaremos en la detección de movimientos con opencv. 

Utilizaremos el método llamado “Differential Images” este consiste en comparar dos imágenes, una la imagen actual capturada por la webcam y la segunda es la imagen anterior, si las dos imágenes son idénticas concluimos en que no hubo movimiento.

Código Detección de Movimientos


Iniciar la webcam y capturar las imágenes actuales además de la anterior para compararlas posteriormente.

VideoCapture cap(0);

if (cap.isOpened())
{
 Mat actFrame, antFrame;

 while (true)
 {
  cap >> actFrame;

  if (!actFrame.empty())
  {
   antFrame = actFrame.clone();
  }

  if (waitKey(30) == 27) break;
 }
}

Restamos las imágenes con la función subtract, a la imagen resultante le aplicamos threshold y morphologyEx, esto ayuda a reducir el ruido de fondo y para finalizar convertimos la imagen a escala de grises.

Mat _kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size2i(3, 3), cv::Point2i(1, 1));
Mat difFrame;

subtract(actFrame, antFrame, difFrame);
threshold(difFrame, difFrame, 15, 255, CV_THRESH_BINARY);
morphologyEx(difFrame, difFrame, CV_MOP_OPEN, _kernel, cv::Point2i(-1, -1), 1);
cvtColor(difFrame, difFrame, CV_BGR2GRAY);

imshow("Movimientos", difFrame);

Con esto tendremos el siguiente resultado en la captura de la webcam. La imagen de la derecha muestra el movimiento, cuando no la haya la imagen estará vacía.

deteccion de movimientomovimiento








Para terminar intentaremos detectar las coordenadas donde se ha producido el movimiento que hemos detectado, lo que haremos será buscar los contornos, luego calculamos el área de los contornos encontrados y nos quedaremos con la mas grande para mostrar solo un rectángulo y no todos los que encuentre la función.

vector<vector<Point>> contours;
vector<Vec4i> hierarchy;

int largest_area = 0;
int largest_contour_index = 0;
Rect bounding_rect;

findContours(difFrame, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

for (size_t i = 0; i < contours.size(); i++) 
{
 double a = contourArea(contours[i], false);

 if (a > largest_area)
 {
  largest_area = a;
  largest_contour_index = i;
  bounding_rect = boundingRect(contours[i]);
 }
}

Mat dst = actFrame.clone();
Scalar color(255, 255, 255);
drawContours(dst, contours, largest_contour_index, color, CV_FILLED, 8, hierarchy);
rectangle(dst, bounding_rect, Scalar(0, 255, 0), 1, 8, 0);

Con lo que tenemos, el rectángulo que muestra el objeto que se mueve no es el mejor pero lo iremos trabajando y mejorando para aplicaciones mas avanzadas.

deteccion de movimiento opencv
Ver Categoria:

5 comentarios :

  1. Estimado,

    muy buena publicación, pero me gustaría saber si existe algún equivalente a la librería tchar.h dentro de linux, que es el entorno en el cual trabajo.


    Saludos.

    ResponderEliminar
    Respuestas
    1. En realidad el encabezado tchar.h lo puedes eliminar pero deberás cambiar el método main para no usar TCHAR, este encabezado no es necesario para este ejemplo, lo introduje sin querer.

      Eliminar
  2. al correrlo solo me muestra la camara, alguna idea de lo que pasa?, de echo tambien con los ejemplos que cargan alguna imagen me manda un error y no los puede abrir, e intentado poniendo la imagen en la misma carpeta y mandarla llamar por la direccion, alguna sugerencia? llevo 2 dias completos tratando de hacer que esto funcione :/

    ResponderEliminar
  3. Hola, soy nuevo en Python y estoy buscando ayuda en la detección de objetos, tienes algo de codigo que me ayude a armar el mio?. Gracias

    ResponderEliminar
    Respuestas
    1. La carpeta opencv-x.x.x\samples\python contiene buenos ejemplos, esta se encuentra en la descarga de OpenCV.

      Eliminar