2012-08-28 23 views
7

Witam Próbuję zrobić trochę przetwarzania obrazu. Używam Microsoft Kinect do wykrywania ludzi w pokoju. Uzyskać dane głębokość, popracować odjęciu tła i kończy się z sekwencji wideo jak ta, kiedy człowiek wchodzi na scenę i spacery:Jak mogę usunąć zakłócenia z tej sekwencji wideo?

http://www.screenr.com/h7f8

umieścić film wideo, dzięki czemu można zobaczyć zachowanie hałas w filmie. Różne kolory reprezentują różne poziomy głębokości. Biały oznacza pusty. Jak widać, jest dość głośno, zwłaszcza czerwone odgłosy.

Muszę pozbyć się wszystkiego, z wyjątkiem człowieka, jak tylko możliwe. Kiedy robię erozję/dylatację (używając bardzo dużego rozmiaru okna), mogę pozbyć się dużo hałasu, ale zastanawiałem się, czy istnieją inne metody, których mogę użyć. Zwłaszcza czerwony szum w filmie jest trudny do usunięcia przy użyciu erozji/dylatacji.

Kilka uwag:

1) Lepsze tło odejmowanie można zrobić, gdybyśmy wiedzieli, kiedy nie ma ludzi na scenie, ale tło odejmowanie robimy, jest w pełni automatyczny i działa nawet wtedy, gdy są ludzie w scenę, a nawet po przeniesieniu kamery itp., więc jest to najlepsze odejmowanie tła, które możemy teraz uzyskać.

2) Algorytm działa w systemie wbudowanym w czasie rzeczywistym. Im skuteczniejszy i łatwiejszy algorytm, tym lepiej. I nie musi to być doskonałe. Chociaż mile widziane są również skomplikowane techniki przetwarzania sygnału (może moglibyśmy użyć ich w innym projekcie, który nie potrzebuje wbudowanego przetwarzania w czasie rzeczywistym).

3) Nie potrzebuję rzeczywistego kodu. Tylko pomysły.

+0

Wiedzieć więcej o odejmowaniu tła może pomóc; czyli dlaczego na obrazie pozostały szumy? – jpa

+0

Jakiego zestawu SDK/sterownika używasz (np. MS Kinect SDK, OpenNI, libfreenect itp.)? –

Odpowiedz

0

Jest to całkiem proste, zakładając, że używasz zestawu SDK Kinect. Chciałbym śledzić this filmy podstaw głębokość i zrobić coś takiego:

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; 
    } 

okaże wszystko z wyjątkiem białych ludzi, a ludzie są złote. Mam nadzieję że to pomoże!

EDIT

wiem, że nie koniecznie chcą kodu tylko pomysły, więc powiedziałbym znaleźć algorytm, który wyznaczy głębokość, i jeden, który znajdzie ilość ludzi i kolor biały wszystko z wyjątkiem ludzie. Dostarczyłem to wszystko, ale nie wiedziałem, czy wiesz, co się dzieje. Mam również obraz końcowego programu.

image1

Uwaga: dodałem drugą ramkę głębokość perspektywy

0

Może się mylę (ja potrzebuję film bez przetworzenia do tego), ale chciałbym powiedzieć, że mają tendencję do ciebie próbują pozbyć się zmian oświetlenia.

To sprawia, że ​​wykrywanie ludzi jest naprawdę trudne w "prawdziwych" środowiskach.

Możesz wyewidencjonować this other SO question dla niektórych linków.

Zwykłem wykrywać ludzi w czasie rzeczywistym w tej samej konfiguracji, co ty, ale z wizją jednooczną. W moim przypadku naprawdę dobrym deskryptorem była wersja LBPs, która jest używana głównie do klasyfikacji tekstur. Jest to bardzo proste w praktyce (istnieją implementacje w całym Internecie).

LBP, które służą do określenia obszaru zainteresowania, w którym wykryty jest ruch, dzięki czemu mogę przetworzyć tylko część obrazu i pozbyć się całego tego szumu.

Ten dokument używa na przykład LBP do korekcji obrazów w skali szarości.

Mam nadzieję, że przyniosą nowe pomysły.

2

Tylko moje dwa centy:

Jeśli nie przeszkadza przy użyciu SDK dla tego, to można bardzo łatwo utrzymać tylko osoba pikseli za pomocą PlayerIndexBitmask jak pokazuje Outlaw Lemur.

Teraz możesz nie chcieć być zależnym od sterowników i chcesz to zrobić na poziomie przetwarzania obrazu. Podejście, które wypróbowaliśmy w projekcie i które działało całkiem dobrze, było oparte na konturze. Zaczęliśmy od odejmowania tła, a następnie wykryliśmy największy kontur na obrazie, zakładając, że jest to osoba (ponieważ zazwyczaj hałas, który pozostał, był bardzo niewielką plamą) i wypełniliśmy ten kontur i zachowaliśmy go. Można również użyć pewnego rodzaju filtrowania medianowego jako pierwszego przejścia.

Oczywiście nie jest to idealne ani odpowiednie w każdym przypadku i prawdopodobnie istnieje wiele lepszych metod. Ale po prostu wyrzucam to na wypadek, gdyby pomogło ci wymyślić jakieś pomysły.

+0

+1 Może to dotyczyć dowolnego języka/źródła –

1

Spójrz na eyesweb.

Jest to platforma do projektowania, która obsługuje urządzenie kinect i można zastosować filtry zakłóceń na wyjściach. Jest to bardzo przydatne i proste narzędzie do projektowania systemów.