Testujemy Face API, czyli czy własną twarzą da się oszukać komputer?

Testujemy Face API, czyli czy własną twarzą da się oszukać komputer?

Łukasz Komosa 20 czerwca 2017

W tym artykule opiszę, jak w kilku prostych krokach rozpocząć pracę z usługą Microsoft Cognitive Services. I przedstawię przykłady wykorzystujące mechanizmy rozpoznawania twarzy, jakie udostępnia nam biblioteka Face-API.

Microsoft Cognitive Services jest usługą Microsoftu, która ujrzała światło dzienne na początku 2016 roku. Udostępnia ona szereg metod wykorzystujących algorytmy uczenia maszynowego, począwszy od wykrywania twarzy, emocji na zdjęciach lub wideo do usług pozwalających na rozpoznawanie tekstu na fotografiach (OCR) czy konwertowania mowy na tekst.

Wszystkie wymienione usługi zostały udostępnione w postaci API w ramach projektu Microsoft Project Oxford. Biblioteka została zaprojektowana w taki sposób aby można było z niej korzystać niemalże dowolnym językiem programowania.

Aby lepiej zapoznać się możliwościami jakie daje nam opisywana usługa zaprezentuję kilka przykładów napisanych w języku C# wykorzystujących podstawowe funkcje Microsoft Cognitive Services związane z mechanizmem rozpoznawania twarzy. Chodzi mianowicie
o Face API. W prezentowanym przykładzie zademonstruję metody, które pozwolą nam na wykonanie następujących czynności:

  • Wykrywanie twarzy na fotografii
  • Analiza miejsc, w których znajdują się źrenice, nos lub usta a następnie zaznaczenie ich na fotografii
  • Analiza pozycji głowy, płci i wieku osoby znajdującej się na fotografii

 

Krok 1: Pozyskanie klucza

Zanim jednak rozpoczniemy pracę, należy zarejestrować się w serwisie Cognitive Services i wygenerować unikalny klucz, który będzie wykorzystywany przy każdym zapytaniu. Dostęp do API jest darmowy, ale ma pewne ograniczenia związane z ilością wykonywanych żądań.

W przypadku Face API jest to 30 000 requestów w ciągu miesiąca co w zupełności wystarcza w dla małych projektów. Osoby zainteresowane wykorzystaniem tej technologii na większą skalę odsyłam do sekcji Pricing options na stronie Cognitive Services.

 

Krok 2: Autoryzacja requestu

Jak już wcześniej wspomniałem, każde zapytanie do Face API wymaga podania klucza naszej subskrypcji, który można przekazać na kilka sposobów.

Pierwszym z nich jest przekazanie klucza API za pomocą parametru w adresie URL:

https://westus.api.cognitive.microsoft.com/face/v1.0/detect[?returnFaceId][&returnFaceLandmarks][&returnFaceAttributes]&subscription-key=<subscription key>

Alternatywnie klucz może zostać ustawiony w nagłówku HTTP jako wartość parametru:

ocp-apim-subscription-key : < subscription key>

Najwygodniejszym spośród wszystkich sposobów jest skorzystanie z klienta pobranego za pomocą NuGet Package Managera i przekazanie klucza API w konstruktorze klasy FaceServiceClient.

var faceServiceClient = new FaceServiceClient("subscription key");

 

Krok 3: Wykrywanie twarzy

Wykrywanie twarzy na zdjęciu odbywa się poprzez wywołanie metody asynchronicznej DetectAsync z żądaniem typu POST. W zależności od przeciążenia metody możemy przesłać wybrany przez nas plik w postaci application/octet-stream lub podać adres URL do obrazu. Pozostałe dwa parametry są opcjonalne i określają, czy chcemy w odpowiedzi otrzymać dodatkowe atrybuty, takie jak: umiejscowienie punktów charakterystycznych danej twarzy oraz jej identyfikator.

Poniższe fragmenty kodu prezentują wywołanie metody DetectAsync na dwa sposoby:

 

using (Stream imageStream = File.OpenRead(imagePath))
  {
       Face[] faces = await faceServiceClient.DetectAsync(imageStream, true, true);

foreach (var face in faces)
       {
    		FaceRectangle rectangle = face.FaceRectangle;
    		FaceLandmarks landmarks = face.FaceLandmarks;
}
  }

Face[] faces = await faceServiceClient.DetectAsync(imageUrl, true, true);

foreach (var face in faces)
{
    FaceRectangle rectangle = face.FaceRectangle;
    FaceLandmarks landmarks = face.FaceLandmarks;
}

 

W rezultacie dla każdej zlokalizowanej twarzy znajdującej się na fotografii otrzymujemy właściwości, które możemy wykorzystać w kolejnym etapie.

Właściwość FaceRectangle zawiera prostokąt w obrębie którego znajdują się najistotniejsze części twarzy, które algorytm wykorzystuje podczas analizy: oczy, brwi, nos i usta. Pozostałe (np. górna część głowy, uszy i podbródek) nie są dołączane, ponieważ nie odgrywają istotnej roli dla algorytmów detekcji.

FaceLandmarks zawiera 27 punktów charakterystycznych, które oznaczają umiejscowienie wcześniej wspomnianych atrybutów. Punkty (podobnie jak w przypadku prostokąta) to wartości pikseli miejsc w których dany element się znajduje. Dzięki temu w bardzo prosty sposób jesteśmy w stanie pobrać ich lokalizację i zaznaczyć je na naszej fotografii.

 

Dodatkowym elementem, na który warto zwrócić uwagę, są atrybuty ułożenia głowy w 3D. Są to współrzędne mówiące, o jaki kąt dana twarz jest obrócona na fotografii. Możemy je wykorzystać np. do wykonywania operacji związanych z przetwarzaniem obrazu i spróbować wyprostować zdjęcie, co pozwoli nam na lepszą weryfikację.

 

Krok 4: Wykorzystanie dodatkowych atrybutów

Poza punktami charakterystycznymi twarzy, Face-API może analizować kilka dodatkowych atrybutów, w których skład wchodzą:

  • Wiek 
  • Płeć
  • Intensywność uśmiechu
  • Zarost
  • Położenie głowy
  • Okulary

Są one przydatne, gdy chcemy na ich podstawie sklasyfikować twarze. Praktyczne zastosowanie tych atrybutów sprawdza się w systemach bazujących na przetwarzaniu cech biometrycznych. W przypadkach, gdy wiek osoby będzie znacząco odbiegał od deklarowanego lub płeć będzie inna. Jednak nie zawsze należy się nimi kierować. Wynika to z faktu, iż są one określane przy użyciu algorytmów statystycznych, przez co nie zawsze pokrywają się z rzeczywistą wartością. Zazwyczaj algorytm myli się przy określaniu wieku danej osoby, natomiast w pozostałych przypadkach poprawność jest całkowicie zadowalająca.

Jeżeli chcemy, aby wykorzystywana przez nas metoda zwróciła nam wyżej opisane atrybuty, należy określić, które z nich chcemy otrzymać przekazując je do metody jako dodatkowy parametr.

Poniższy fragment kodu przedstawia przykład wywołania metody DetectAsync z przekazaniem dodatkowych parametrów:

 

Face[] faces = await faceServiceClient.DetectAsync(imageUrl,
                true,
                true,
                new FaceAttributeType[] {
                        FaceAttributeType.Age,
                        FaceAttributeType.Gender,
                        FaceAttributeType.Smile,
                        FaceAttributeType.FacialHair,
                        FaceAttributeType.HeadPose,
                        FaceAttributeType.Glasses
                });

            foreach (var face in faces)
            {
                Guid id = face.FaceId;
                FaceRectangle rectangle = face.FaceRectangle;
                FaceLandmarks landmarks = face.FaceLandmarks;
                FaceAttributes attributes = face.FaceAttributes;
   
                double age = attributes.Age;
                string gender = attributes.Gender;
                double smile = attributes.Smile;
                FacialHair facialHair = attributes.FacialHair;
                HeadPose headPose = attributes.HeadPose;
                Glasses glasses = attributes.Glasses;
            }
W celu zobrazowania działania algorytmu przeprowadziłem kilka testów na grupie własnych zdjęć wykonanych na przestrzeni roku. Moja aplikacja oprócz detekcji twarzy na fotografii badała takie atrybuty jak: płeć, wiek, intensywność uśmiechu oraz to, czy osoba na zdjęciu nosi okulary.

 

Test nr 1

 

Test nr 2

 

Test nr 3

 

Test nr 4

 

 

Przeprowadzone badania wskazują, że w niektórych przypadkach rezultaty mogą być nieco zaskakujące. Rzeczywisty wiek wskazał jedynie test nr 1. Okazuje się, że w bardzo prosty sposób można próbować oszukać algorytm, wykonując różnego rodzaju operacje na pliku.

Najlepiej obrazuje to badanie nr 2, w którym wykorzystałem tą samą fotografię z tym, że nałożyłem kilka filtrów oraz delikatnie obróciłem zdjęcie. W rezultacie otrzymałem inne wyniki dotyczące wieku oraz intensywności uśmiechu.

Podobnie w przypadku fotografii nr 3, na której twarz widoczna jest jedynie z profilu, algorytm wskazał wiek odbiegający od rzeczywistej wartości. Skuteczność działania algorytmu można poprawić wykorzystując mechanizmy grupowania, ale o tym opowiem w kolejnym wpisie.

 

Podsumowanie

W tym artykule skupiłem się na przekazaniu informacji, jak w kilku prostych krokach rozpocząć pracę z Micorosft Face-API. Dla zobrazowania działania całego mechanizmu detekcji twarzy wykonałem kilka testów, w których pokazałem, jak z niego korzystać. Face-API pozwala na realizację wielu ciekawych projektów wykorzystujących mechanizmy rozpoznawania twarzy, których skuteczność działania robi ogromne wrażenie. Przedstawione przykłady stanowią jedynie część możliwości, jakie oferuje nam ta biblioteka.

Wykorzystanie pozostałych funkcjonalności skupiających się na grupowaniu oraz weryfikacji twarzy omówię w kolejnych wpisach. Do zobaczenia!

 

Łukasz Komosa, FinAi.com

Warszawa, 20 czerwca 2017 roku

Location icon Facebook icon Twitter icon Google+ icon LinkedIn icon Technology icon Business icon Marketing icon Phone icon Mail icon User icon Tag icon Bubble icon Arrow right icon Arrow left icon Calendar PR Contact