Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

607
Vistas
EmguCV: ¿Dibujar el contorno de un objeto en movimiento usando el flujo óptico?

Me gustaría hacer detección de movimiento en C# (usando EmguCV 3.0) para eliminar objetos en movimiento o en primer plano para dibujar una superposición.

Aquí hay una prueba de muestra que hice con un Kinect (porque es una cámara de profundidad)Demostración con Kinect

¿Cómo puedo comenzar con EmguCV 3.0?

  • Probé muchos códigos de eliminación de fondo que no funcionan
  • Parece que OpticalFlow es un buen comienzo pero no hay ejemplo en EmguCV 3.0
  • Si encuentro la mancha más grande, ¿cómo puedo encontrar sus contornos?

¿Puede alguien ayudarme a empezar?

EDITADO: 17/06/2015

En EmguCV3.0.0 RC no veo OpticalFlow en el paquete y la documentación: http://www.emgu.com/wiki/files/3.0.0-rc1/document/html/b72c032d-59ae-c36f-5e00-12f8d621dfb8 .htm

Solo hay: DenseOpticalFlow, OpticalFlowDualTVL1 ???

Este es un código AbsDiff:

 var grayFrame = frame.Convert<Gray, Byte>(); var motionFrame = grayFrame.AbsDiff(backFrame) .ThresholdBinary(new Gray(20), new Gray(255)) .Erode(2) .Dilate(2);

Resultado:Diferencia de demostración

No sé cómo obtener el movimiento en blanco?

Este es el código del blob:

 Image<Bgr, Byte> smoothedFrame = new Image<Bgr, byte>(frame.Size); CvInvoke.GaussianBlur(frame, smoothedFrame, new Size(3, 3), 1); //filter out noises Mat forgroundMask = new Mat(); fgDetector.Apply(smoothedFrame, forgroundMask); CvBlobs blobs = new CvBlobs(); blobDetector.Detect(forgroundMask.ToImage<Gray, byte>(), blobs); blobs.FilterByArea(400, int.MaxValue); blobTracker.Update(blobs, 1.0, 0, 1); foreach (var pair in blobs) { CvBlob b = pair.Value; CvInvoke.Rectangle(frame, b.BoundingBox, new MCvScalar(255.0, 255.0, 255.0), 2); }

Resultado:Demostración de blobs

¿Por qué tanto falso positivo?

Este es un código MOG2:

 forgroundDetector.Apply(frame, forgroundMask); motionHistory.Update(forgroundMask); var motionMask = GetMotionMask(); Image<Bgr, Byte> motionImage = new Image<Bgr, byte>(motionMask.Size); CvInvoke.InsertChannel(motionMask, motionImage, 0); Rectangle[] rects; using (VectorOfRect boundingRect = new VectorOfRect()) { motionHistory.GetMotionComponents(segMask, boundingRect); rects = boundingRect.ToArray(); } foreach (Rectangle comp in rects) { ...

Resultado:Demostración de MOG2

Si selecciono el Área más grande, ¿cómo puedo obtener el contorno del objeto?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Primero, puedo darle un ejemplo de código de flujo óptico.

Deje que oldImage y newImage sean variables que contienen el marco anterior y actual. En mi código, es de tipo Image<Gray, Byte> .

 // prep containers for x and y vectors Image<Gray, float> velx = new Image<Gray, float>(newImage.Size); Image<Gray, float> vely = new Image<Gray, float>(newImage.Size); // use the Horn and Schunck dense optical flow algorithm. OpticalFlow.HS(oldImage, newImage, true, velx, vely, 0.1d, new MCvTermCriteria(100)); // color each pixel Image<Hsv, Byte> coloredMotion = new Image<Hsv, Byte>(newImage.Size); for (int i = 0; i < coloredMotion.Width; i++) { for (int j = 0; j < coloredMotion.Height; j++) { // Pull the relevant intensities from the velx and vely matrices double velxHere = velx[j, i].Intensity; double velyHere = vely[j, i].Intensity; // Determine the color (ie, the angle) double degrees = Math.Atan(velyHere / velxHere) / Math.PI * 90 + 45; if (velxHere < 0) { degrees += 90; } coloredMotion.Data[j, i, 0] = (Byte) degrees; coloredMotion.Data[j, i, 1] = 255; // Determine the intensity (ie, the distance) double intensity = Math.Sqrt(velxHere * velxHere + velyHere * velyHere) * 10; coloredMotion.Data[j, i, 2] = (intensity > 255) ? 255 : intensity; } } // coloredMotion is now an image that shows intensity of motion by lightness // and direction by color.

Con respecto a la cuestión más amplia de cómo eliminar el primer plano:

Si tuviera una forma de obtener una imagen de fondo estática, esa es la mejor manera de comenzar. Luego, el primer plano sería detectado por el método AbsDiff y usando Erode and Dilate o Gaussian para suavizar la imagen, luego usaría la detección de manchas.

Para la detección simple de primer plano, encontré que el flujo óptico era demasiado procesado (8 fps máx.), mientras que el método AbsDiff era igual de preciso pero no tenía efecto en la velocidad de fotogramas.

Con respecto a los contornos, si solo busca encontrar el tamaño, la posición y otros momentos, entonces la detección de manchas en el tutorial de AbsDiff anterior parece ser suficiente, que usa Image.FindContours(...) .

Si no, comenzaría a buscar en la clase CvBlobDetector como se usa en este tutorial . Hay una función DrawBlob incorporada que puede ser útil.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda