BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











KinSector - Monitoruj pomieszczenie z Kinect dla Windows

14-12-2013 17:54 | Tomasz Kowalczyk
Artykuł ten stanowi przykład wykorzystania T-Mobile OpenAPI wraz z sensorem ruchu Microsoft Kinect. Aplikacja, która zostanie poniżej opisana pozwala na monitorowanie dowolnego pomieszczenia oraz śledzenie ruchu osób znajdujących się w nim.

Artykuł ten stanowi przykład wykorzystania T-Mobile OpenAPI wraz z sensorem ruchu Microsoft Kinect. Aplikacja, która zostanie poniżej opisana pozwala na monitorowanie dowolnego pomieszczenia oraz śledzenie ruchu osób znajdujących się w nim. W oparciu o mechanizmy OpenAPI na zdefiniowany numer telefonu komórkowego będą przychodziły powiadomienia w postaci MMS i SMS w zależności od wystąpienia danego zdarzenia w monitorowanym pomieszczeniu. Przygotowana aplikacja stanowi łatwo rozszerzalny przykład możliwy do rozbudowy, pozwalając wykorzystać możliwości współczesnej techniki w domach, biurach itp.

Po przeczytaniu tego artykułu będziesz wiedział/a:

  • Jak korzystać z T-Mobile OpenAPI w środowisku .NET w oparciu o język C#
  • Co to jest Microsoft Kinect
  • Jak wykryć pojawiającą się osobę w pomieszczeniu
  • Jak programowo reagować na wybrane gesty
  • Jak rozpoznawać mowę
  • Jak budować wiadomości MMS i SMS dzięki T-Mobile OpenAPI

Funkcjonalność aplikacji KinSector będzie oparta o trzy przykłady zastosowania:

  1. W momencie pojawienia się człowieka w monitorowanym pomieszczeniu aplikacja poprzez sensor Kinect powinna zrobić jej zdjęcie, przygotować odpowiednią wiadomość MMS wraz ze zdjęciem oraz wysłać ją na zdefiniowany wcześniej numer w oparciu o T-Mobile OpenAPI
  2. W przypadku gdy osoba znajdująca się w monitorowanym pomieszczeniu uniesie ręce ponad głowę (spodziewane zachowanie po komendzie „ręce do góry" ;-D ). Aplikacja powinna wysłać alarmowego SMS pod wcześniej zdefiniowany numer.
  3. W sytuacji gdy w monitorowanym pomieszczeniu padnie jedno z wcześniej zdefiniowanych słów znajdujących się w słowniku (Hello, Help), aplikacja powinna rozpoznać żądane słowo a następnie dołączyć je do treści SMS, który następnie zostanie wysłany pod dany numer telefonu.

W celu realizacji opisanych wyżej scenariuszy użycia aplikacji niezbędne jest wykorzystanie sensora Microsoft Kinect oraz możliwości jakie daje T-Mobile OpenAPI.

Znakomity sukces marketingowy urządzenia Kinect dla konsoli Xbox 360 (sprzedaż w 2011 roku osiągnęła liczbę 18 milionów sztuk i tym samym trafiła do księgi rekordów Guinnessa z czego 8 milionów zostało sprzedanych w ciągu 60 dni), spowodował rozpoczęcie prac nad wersją dedykowaną dla użytkowników komputerów osobistych. Początkowo sensor posiadał niewielkie wsparcie dla osób, które chciały wykorzystać jego potencjał w swoich aplikacjach. Jednak ogromne zainteresowanie społeczności wymusiło na producencie wydanie oficjalnych bibliotek programistycznych – SDK (SDK – ang. Software Development Kit).

Architektura sprzętowa urządzenia została przedstawiona poniżej:

  1. Emiter podczerwieni - Emituje wiązkę promieni podczerwonych, które odbijając się do powierzchni zniekształcają się i następnie są odczytywane przez kamerę głębokości.
  2. Kamera RGB - Działa podobnie jak kamera internetowa, przesyła serie obrazów do komputera z prędkością 30 klatek na sekundę. Potrafi pracować w rozdzielczości 1280x1024 piksele, jednak standardowo działa w trybie 640x480pikseli
  3. Kamera głębokości - Analizuję zniekształconą przez obiekt wiązkę promieni podczerwonych tworząc model 3D pomieszczenia i obiektów znajdujących się w nim. Działa w rozdzielczości 320x240 pikseli.
  4. Kontroler nachylenia - Dostosowuje położenie sensora w sposób automatyczny w zależności od rozmiarów śledzonych obiektów. Pozwala zmieniać położenie sensora o 27 stopni w pionie.
  5. Zestaw mikrofonów - Zestaw składa się z 4 mikrofonów, które wykorzystywane są przez funkcje rozpoznawania mowy. Mikrofony te posiadają funkcję filtrującą zakłócenia oraz obsługują DSP (Digital Signal Processing). Potrafią również zlokalizować źródło dźwięku.
  6. Kabel połączeniowy - Nie jest to zwykły kabel z gniazdem USB z tego względu do połączenia sensora Kinect z komputerem potrzebny jest dodatkowy zasilacz z kablem USB.

Powyższe informacje stanowią jedynie wstęp do sensora Kinect oraz jego możliwości. W razie chęci zgłębienia tematu dobrze jest zapoznać się z następującymi artykułami.

Mechanizmy OpenAPI funkcjonują w zgodzie z architekturą REST korzystanie z nich w środowisku .NET w oparciu o język C# jest więc niezwykle proste. Należy tutaj skorzystać z możliwości jakie daje nam klasa WebRequest. Najprostszy z możliwych przykładów pokazujących jak korzystać z OpenAPI w środowisku .NET znajduję się tutaj.

Niezbędne jest zdefiniowanie adresu połączenia dla usług OpenAPI:

private const string queryURL = "https://developers.t-mobile.pl/api/messaging/";
 

Następnie należy zbudować odpowiedni query string w zależności od funkcji jaka ma być użyta:

string querySMS = string.Format("sms?to={0}&text={1}&appkey={2}", TelephoneNumber, TextToSend, AppKey);
 

Ostatnim krokiem jest zgodnie z dokumentacją klasy WebRequest użyć jej właściwości oraz przesłać dane do serwera OpenAPI:

var uri = new Uri(string.Format(queryURL + querySMS));
                if (uri.Scheme == Uri.UriSchemeHttps)
                {
                    var request = WebRequest.Create(uri);
                    request.Method = WebRequestMethods.Http.Get;
                    using (var response = request.GetResponse())
                    {
                        using(var leader = new StreamReader(response.GetResponseStream()))
                        {
                            string tmp = reader.ReadToEnd();
                            Console.WriteLine(tmp);
                        }
                    }
                }

Schemat działania aplikacji przedstawia poniższy diagram:

W celu wykrycia osoby należy przede wszystkim zdefiniować właściwość, która w zależności od tego czy jakaś osoba będzie w zasięgu sensora czy nie, zostanie ustawiana na wartość true lub false.

bool AreSkeletonsBeingTracked
        {
            get { return tracking; }
            set
            {
                if (tracking != value)
                {
                    TakePhoto(kinectPhoto);
                    SendAlertViaMMS(TelNumb, MMSTitle);
                }

                tracking = value;
            }
        }

Następnie w kodzie programu należy umieścić fragment, który odpowiednio przypisuje wartość dla wcześniej zdefiniowanej właściwości:

AreSkeletonsBeingTracked = allSkeletons.Any(x =>
                x.TrackingState == SkeletonTrackingState.Tracked);

Dzięki wbudowanej kamerze RGB sensora, programista jest w stanie w łatwy sposób przechwycić z niej obraz i następnie zapisać na dysku w formacie np. *.jpg. Kod odpowiedzialny za wykonanie zdjęcie wykrytej osobie:

using (FileStream savedSnapshot = new FileStream(FileNameToSave, FileMode.Create))
                {
                    BitmapSource image = (BitmapSource)kinectColorView.Source;
                    JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
                    jpgEncoder.QualityLevel = 70;
                    jpgEncoder.Frames.Add(BitmapFrame.Create(image));
                    jpgEncoder.Save(savedSnapshot);
                    savedSnapshot.Flush();
                    savedSnapshot.Close();
                    savedSnapshot.Dispose();
                }

Bazując na dokumentacji OpenAPI, wysłanie MMS ze zdjęciem prezentuje się następująco. Należy tutaj zwrócić uwagę na ustawienie typu danych jakie zostaną przesłane do serwera OpenAPI. Metoda wysyłająca MMS ze zdjęciem na zdefiniowany numer:

byte[] bytes = null;
                FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                long numBytes = new FileInfo(FilePath).Length;
                bytes = br.ReadBytes((int)numBytes);
                var uri = new Uri(string.Format(queryURL + queryMMS));
                if (uri.Scheme == Uri.UriSchemeHttps)
                {
                    var request = WebRequest.Create(uri);
                    request.Method = WebRequestMethods.Http.Post;
                    request.ContentType = "image/jpg";
                    request.ContentLength = bytes.Length;
                    using (var stream = request.GetRequestStream())
                    {
                        stream.Write(bytes, 0, bytes.Length);
                    }
                    using (var response = request.GetResponse())
                    {
                        using (var reader = new StreamReader(response.GetResponseStream()))
                        {
                            string tmp = reader.ReadToEnd();
                            Console.WriteLine(tmp);
                        }
                    }
                }

Zaimplementowany został przykładowy gest możliwy do wykonania przez osobę znajdującą się pomieszczeniu – podniesienie rąk do góry. Łatwo tutaj wyobrazić sobie możliwość zajścia takiej sytuacji np. w banku lub sklepie gdzie siedzący kasjer w momencie wtargnięcia napastnika zmuszony jest unieść swe ręce do góry i nie ruszać się. W takiej sytuacji aplikacja nie zależnie do innych działających systemów wysyła alarmowego SMS lub np. zestawia połączenie z policją.

bool AreHandsBeingAbove
        {
            get { return handsAbove; }
            set
            {
                if (handsAbove != value)
                {
                    SendAlertViaSMS(TelNumb, SMSContent);
                }

                handsAbove = value;
            }
        }
 

Ustawienie wartości dla zdefiniowanej właściwości zachodzi momencie podniesienia rąk ponad głowę. Określone to zostało dzięki wartości współrzędnej przechowującej położenie trzech części ciała biorących udział w zdarzeniu: głowy, lewej i prawej dłoni.

if (SkeletonTrackingState.Tracked == skeleton.TrackingState)
                    {
                        if ((skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.Head].Position.Y) &&
                            (skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.Head].Position.Y))
                        {
                            handsAbove = true;
                            break;
                        }
                        else
                        {
                            handsAbove = false;
                        }
                    }
 

W kolejnym kroku następuje wysłanie SMS. Kod wywołujący taką akcję został przedstawiony wyżej.

Funkcja rozpoznawania mowy działa w oparciu o Microsoft Speech API, które to pozwala m.in. definiować słownik słów lub zwrotów możliwych do rozpoznania w postaci wygodnego pliku XML, który daje się modyfikować za pomocą dowolnego edytora tekstu. Tym samym istnieje możliwość zwiększenia ilości możliwych słów do rozpoznania.

var g = new Microsoft.Speech.Recognition.Grammar(_grammarPath);
                    speechEngine.LoadGrammar(g);

                    speechEngine.SpeechRecognized += SpeechRecognized;
                    speechEngine.SpeechRecognitionRejected += SpeechRejected;
                    speechEngine.SetInputToAudioStream(
                        _sensor.AudioSource.Start(), new SpeechAudioFormatInfo(EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, null));
                    speechEngine.RecognizeAsync(RecognizeMode.Multiple);
 

Przykładowy plik słownika zgodny ze strukturą plików XML został przedstawiony poniżej. W razie zamiaru zwiększania liczby rozpoznawanych słów należy dodać kolejne umieszczając je między znacznikiem item:

<grammar version="1.0" xml:lang="en-US" root="rootRule" tag-format="semantics/1.0-literals" xmlns="http://www.w3.org/2001/06/grammar">
  <rule id="rootRule">
    <one-of>
      <item>Hello</item>
      <item>Help</item>
    </one-of>
  </rule>
</grammar>
 

W momencie gdy jedno ze słów znajdujących się w słowniku zostało rozpoznane z określoną dokładnością (tutaj współczynnik ten został ustawiony na 0.8) przygotowywana jest treść SMS i następnie przekazana ona zostaje do metody łączącej się z OpenAPI i wiadomość zostaje wysłana.

const double ConfidenceThreshold = 0.8;
            if (e.Result.Confidence >= ConfidenceThreshold)
            {
                string content = "Someone said one of warning words: " + e.Result.Text;
                SendAlertViaSMS(TelNumb, content);
            }
 

Kod źródłowy aplikacji przygotowanej na potrzeby niniejszego artykułu znajduję się na portalu GitHub pod adresem: KinSector.

Aby przetestować aplikacje należy przede wszystkim posiadać sensor Kinect. Następnie należy pobrać Kinect for Windows SDK. Do uruchomienia projektu pobranego z repozytorium wystarczy darmowa wersja Express środowiska Visual Studio.

Artykuł ten miał na celu pokazanie jak wszechstronne może być wykorzystanie T-Mobile OpenAPI. Przedstawione tutaj rozwiązanie bazujące na sensorze ruchu Microsoft Kinect można bez większego wysiłku dowolnie rozbudować i używać w swoim domu lub miejscu pracy by śledzić aktywność innych podczas naszej nieobecności.

Jeśli interesują Cię inne przykłady zastosowania sensora Kinect zapraszam na swoją stronę internetową do działu Projects.

Źródło: https://github.com/tkowalczyk/KinSector
tagi: C# Kinect

Komentarze 0

pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.