Detección de movimientos OpenCV

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

Descargar código fuente

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
  4. Hola muy buenos tu tutoriales los e seguido


    Sabes cómo hacer una línea virtual que al atravesarla de alarma

    ResponderEliminar
    Respuestas
    1. De momento no se como hacerlo, pero, es una buena idea, la tomaré en cuenta para tutoriales futuros, gracias por tu interés.

      Eliminar
  5. Buenas, está el código completo en algún lado?

    ResponderEliminar
    Respuestas
    1. Puedes descargar el código en:
      https://www.dropbox.com/s/ijwdv89eskmpz4a/DetectorMovimiento.rar?dl=0

      Eliminar
  6. Hola! Estoy trabajando en mi tesis de grado y necesito saber si con OpenCV es viable hacer que al mirar hacia la izquierda o derecha seleccione una opción u otra. Necesito que lo haga en una grabación en vivo desde la camara de un teléfono por ejemplo, los ejemplos que hay utilizan la detección pero sobre videos ya grabados.

    Aguardo respuesta!
    Toda información ayuda.
    MUCHAS GRACIAS!

    ResponderEliminar

Publicar un comentario

Temas relacionados

Entradas populares de este blog

tkinter Grid

tkinter Canvas

Histogramas OpenCV Python

Python Binance API