2012-08-28 27 views
7

Hola, estoy intentando hacer algunos procesamientos de imagen. Uso Microsoft Kinect para detectar humanos en una habitación. Puedo recuperar los datos de profundidad, hacen un trabajo de sustracción de fondo y terminan con una secuencia de video como este cuando una persona entra en la escena y se pasea por:¿Cómo puedo eliminar el ruido de esta secuencia de video?

http://www.screenr.com/h7f8

pongo un video para que pueda ver el comportamiento de el ruido en el video. Los diferentes colores representan diferentes niveles de profundidad. Blanco representa vacío. Como pueden ver, es bastante ruidoso, especialmente los ruidos rojos.

Necesito deshacerme de todo menos del humano tanto como sea posible. Cuando hago erosión/dilatación (usando un tamaño de ventana muy grande) puedo deshacerme de mucho ruido, pero me pregunto si hay otros métodos que pueda usar. Especialmente el ruido rojo en el video es difícil de eliminar usando la erosión/dilatación.

Algunas notas:

1) Una mejor sustracción de fondo se podría hacer si sabíamos cuando no hay seres humanos en la escena, pero la sustracción de fondo que hacemos es totalmente automática y funciona incluso cuando hay humanos en el escena e incluso cuando la cámara se mueve, etc. por lo que esta es la mejor resta de fondo que podemos obtener en este momento.

2) El algoritmo funcionará en un sistema integrado, en tiempo real. Por lo tanto, cuanto más eficiente y fácil sea el algoritmo, mejor. Y no tiene que ser perfecto. Aunque también son bienvenidas las técnicas de procesamiento de señales complicadas (tal vez podríamos usarlas en otro proyecto que no necesita procesamiento embebido en tiempo real).

3) No necesito un código real. Solo ideas.

+0

Saber más acerca de la resta de fondo podría ayudar; es decir, ¿por qué queda ruido en la imagen? – jpa

+0

¿Qué SDK/controlador estás usando (por ejemplo, MS Kinect SDK, OpenNI, libfreenect, etc.)? –

Respuesta

0

Esto es bastante simple suponiendo que está utilizando Kinect SDK. Yo sigo this de vídeo para lo básico de profundidad, y hacer algo como esto:

private byte[] GenerateColoredBytes(DepthImageFrame depthFrame) 
    { 

     //get the raw data from kinect with the depth for every pixel 
     short[] rawDepthData = new short[depthFrame.PixelDataLength]; 
     depthFrame.CopyPixelDataTo(rawDepthData); 

     //use depthFrame to create the image to display on-screen 
     //depthFrame contains color information for all pixels in image 
     //Height x Width x 4 (Red, Green, Blue, empty byte) 
     Byte[] pixels = new byte[depthFrame.Height * depthFrame.Width * 4]; 

     //Bgr32 - Blue, Green, Red, empty byte 
     //Bgra32 - Blue, Green, Red, transparency 
     //You must set transparency for Bgra as .NET defaults a byte to 0 = fully transparent 

     //hardcoded locations to Blue, Green, Red (BGR) index positions  
     const int BlueIndex = 0; 
     const int GreenIndex = 1; 
     const int RedIndex = 2; 


     //loop through all distances 
     //pick a RGB color based on distance 
     for (int depthIndex = 0, colorIndex = 0; 
      depthIndex < rawDepthData.Length && colorIndex < pixels.Length; 
      depthIndex++, colorIndex += 4) 
     { 
      //get the player (requires skeleton tracking enabled for values) 
      int player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask; 

      //gets the depth value 
      int depth = rawDepthData[depthIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth; 

      //.9M or 2.95' 
      if (depth <= 900) 
      { 
       //we are very close 
       pixels[colorIndex + BlueIndex] = Colors.White.B; 
       pixels[colorIndex + GreenIndex] = Colors.White.G; 
       pixels[colorIndex + RedIndex] = Colors.White.R; 
      } 
      // .9M - 2M or 2.95' - 6.56' 
      else if (depth > 900 && depth < 2000) 
      { 
       //we are a bit further away 
       pixels[colorIndex + BlueIndex] = Colors.White.B; 
       pixels[colorIndex + GreenIndex] = Colors.White.G; 
       pixels[colorIndex + RedIndex] = Colors.White.R; 
      } 
      // 2M+ or 6.56'+ 
      else if (depth > 2000) 
      { 
       //we are the farthest 
       pixels[colorIndex + BlueIndex] = Colors.White.B; 
       pixels[colorIndex + GreenIndex] = Colors.White.G; 
       pixels[colorIndex + RedIndex] = Colors.White.R; 
      } 


      ////equal coloring for monochromatic histogram 
      //byte intensity = CalculateIntensityFromDepth(depth); 
      //pixels[colorIndex + BlueIndex] = intensity; 
      //pixels[colorIndex + GreenIndex] = intensity; 
      //pixels[colorIndex + RedIndex] = intensity; 


      //Color all players "gold" 
      if (player > 0) 
      { 
       pixels[colorIndex + BlueIndex] = Colors.Gold.B; 
       pixels[colorIndex + GreenIndex] = Colors.Gold.G; 
       pixels[colorIndex + RedIndex] = Colors.Gold.R; 
      } 

     } 


     return pixels; 
    } 

Esto convierte a todo, excepto los seres humanos blancos, y los seres humanos son de oro. ¡Espero que esto ayude!

EDITAR

Sé que no necesariamente quiere código sólo ideas, así que diría que encontrar un algoritmo que encuentra la profundidad, y que encuentra la cantidad de seres humanos, y el color blanco todo, excepto el humanos. He proporcionado todo esto, pero no sabía si sabías lo que estaba pasando. También tengo una imagen del programa final.

image1

Nota: He añadido el segundo cuadro de profundidad de la perspectiva

0

puedo estar equivocado (que necesitaría el video sin procesamiento para eso) pero me tienden a decir que usted están tratando de deshacerse de los cambios de iluminación.

Esto es lo que hace que la detección de personas sea realmente difícil en entornos 'reales'.

Puede consultar this other SO question para algunos enlaces.

Solía ​​detectar a los humanos en tiempo real en la misma configuración que tú, pero con visión monocular. En mi caso, un descriptor realmente bueno fue el LBPs, que se usa principalmente para la clasificación de texturas. Esto es bastante simple de poner en práctica (hay implementaciones en toda la web).

Los LBPs se usaban básicamente para definir un área de interés donde se detecta movimiento, de modo que puedo procesar solo parte de la imagen y deshacerme de todo ese ruido.

Este papel, por ejemplo, utiliza LBP para la corrección de imágenes en escala de grises.

Espero que traiga algunas ideas nuevas.

2

Sólo mis dos centavos:

Si no les importa usar el SDK para que, a continuación, usted puede mantener muy fácilmente sólo los píxeles persona que utiliza el PlayerIndexBitmask como muestra fuera de la ley lémur.

Ahora puede que no desee ser confiable en los controladores para eso y desea hacerlo en un nivel de procesamiento de imágenes. Un enfoque que habíamos probado en un proyecto y que funcionó bastante bien fue basado en el contorno. Comenzamos por una resta de fondo y luego detectamos el contorno más grande en la imagen, suponiendo que esta era la persona (ya que generalmente el ruido que quedaba era muy pequeño) y llenamos ese contorno y lo mantuvimos. También podría usar algún tipo de filtrado mediano como primer paso.

Por supuesto, esto no es perfecto ni adecuado en todos los casos y, probablemente, hay métodos mucho mejores. Pero lo estoy tirando por ahí en caso de que te ayude a pensar en cualquier idea.

+0

+1 Esto puede aplicar para cualquier idioma/fuente –

1

Eche un vistazo a eyesweb.

Es una plataforma para el diseño que admite dispositivos kinect y puede aplicar filtros de ruido en las salidas. Es una herramienta muy útil y simple para el diseño de sistemas multimodal.

Cuestiones relacionadas