Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

602
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!