顔認識APIを使って写真に黒縁メガネをかける
※前ページからの続きです。
GridViewから任意の画像が選択された時の処理
リストであるmyImageList(要素の内容テキストを保持している)内の、GridViewから選択されたインデックスに該当する画像名を変数selectImageに格納します。選択された画像名をサーバーにアップしておいたASP.NETファイルのImageDataフォルダーと連結した文字列を作成して、変数selectImageUriに格納します。
640×480サイズのImageのSourceプロパティに、Uriクラスとして作成した、SelectImageUriを指定します。Image1に実寸の画像が表示されます。[黒縁メガネ]ボタンの使用を可能にします。
Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged Dim selectImage As String = myImageList(GridView1.SelectedIndex) selectImageUri = "ユーザーのサーバー名/ImageFileUpload/ImageData/" &selectImage Image1.Source = New BitmapImage(New Uri(selectImageUri, UriKind.Absolute)) glassesButton.IsEnabled = True End Sub
[黒縁メガネ]ボタンがクリックされた時の処理
API へのリクエストは、apikeyや画像のurlなどの条件を下記のような URL で指定します(REST)。
apikeyには「認証キー」を指定します。urlには作成したメンバ変数selectImageUriオブジェクトを指定します。
Dim imageUri As String = String.Format("https://kaolabo.com/api/detect?apikey={0}&url={1}", AppID, selectImageUri)
新しいHttpClientのインスタンスmyHttpClientオブジェクトを作成します。HttpClientクラスは、URIで識別されたリソースにHTTP要求を送信し、そのリソースからHTTP応答を受信するためのクラスです。
GetStringAsyncメソッドで、指定したURIにGET要求を送信し、非同期操作で応答本体を文字列として返し、変数resultに格納します。
このままだと、名前空間が付加されていて、うまくXMLの内容を取得できませんので、ルート要素
一人だけの顔を認識して返されるデータは図5のようなデータです。
書き換えた結果XMLを、XElement.Parseメソッドで読み込みます。
Descendantsメソッドで、子孫要素であるすべての
Ellipseの新しいインスタンスmyEllipseRight(右目のメガネ)を作成します。
顔の高さ”height”属性の値が100より小さかった場合、大きかった場合の、メガネの位置を調整する数値を変数に格納しておきます。
myEllipseRightをGrayで塗りつぶします。
SetValueメソッドでLeftPropertyとTopPropertyに値を指定して、メガネを表示する右目の位置を設定します。メガネの直径は顔の高さの1/4の大きさとしています。
メガネの縁を黒縁にし、縁の太さを2に設定します。Opacityに0.8を指定して半透明化しておきます。
次に左目のメガネを作成します。右目の設定とまったく同じです。
myCanvasとい名前のCanvasにAddメソッドでmyEllipseRight(右目のメガネ)とmyEllipseLeft(左目のメガネ)を追加します。これで、人物上の両目に半透明のグレーで黒縁のメガネが表示されます。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。
Private Async Sub glaseesButton_Click(sender As Object, e As RoutedEventArgs) Handles glassesButton.Click Dim imageUri As String = String.Format("https://kaolabo.com/api/detect?apikey={0}&url={1}", AppID, selectImageUri) Dim myHttpClient As New HttpClient Dim result = Await myHttpClient.GetStringAsync(New Uri(imageUri, UriKind.Absolute)) result = result.Replace("<results version=" &ChrW(34) & "1.0" &ChrW(34) & " xmlns=" &ChrW(34) & "http://xmlns.kaolabo.com/detect" &ChrW(34) & ">", "<results>") Dim readXmldoc As XElement = XElement.Parse(result) Dim x_no As Integer = 0 Dim y_no As Integer = 0 For Each myResult In From c In readXmldoc.Descendants("face") Select c Dim left_eyeX = CInt(CInt(myResult.Element("left-eye").Attribute("x").Value)) Dim left_eyeY = CInt(CInt(myResult.Element("left-eye").Attribute("y").Value)) Dim faceHeight = CInt(myResult.Attribute("height").Value) Dim right_eyeX = CInt(CInt(myResult.Element("right-eye").Attribute("x").Value)) Dim right_eyeY = CInt(CInt(myResult.Element("right-eye").Attribute("y").Value)) myEllipseRight = New Ellipse If faceHeight<= 100 Then x_no = 20 y_no = 15 Else x_no = 20 y_no = 40 End If With myEllipseRight .Fill = New SolidColorBrush(Colors.Gray) .SetValue(Canvas.LeftProperty, right_eyeX - x_no) .SetValue(Canvas.TopProperty, right_eyeY - y_no) .Width = CInt(faceHeight / 4) .Height = CInt(faceHeight / 4) .Stroke = New SolidColorBrush(Colors.Black) .StrokeThickness = 2 .Opacity = 0.8 End With myEllipseLeft = New Ellipse With myEllipseLeft .Fill = New SolidColorBrush(Colors.Gray) .SetValue(Canvas.LeftProperty, left_eyeX - x_no) .SetValue(Canvas.TopProperty, left_eyeY - y_no) .Width = faceHeight / 4 .Height = faceHeight / 4 .Stroke = New SolidColorBrush(Colors.Black) .StrokeThickness = 2 .Opacity = 0.8 End With myCanvas.Children.Add(myEllipseRight) myCanvas.Children.Add(myEllipseLeft) Next End Sub
[クリア]ボタンがクリックされた時の処理
左目のEllipseと右目のEllipseを非表示にします。
Private Sub clearButton_Click(sender As Object, e As RoutedEventArgs) Handles clearButton.Click myEllipseLeft.Visibility = Xaml.Visibility.Collapsed myEllipseRight.Visibility = Xaml.Visibility.Collapsed End Sub End Class
今回はここまでです。ありがとうございました。
顔認識APIを使って写真に黒縁メガネをかけるアプリサンプル
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Kinectで得た人体情報を転送して、Windows Phoneの画面上に関節の位置を表示してみる
- フリーハンドで書いた住所を認識してBing Map上に表示する
- お花とクラウディアさんを合成して表示するプログラムを作る
- 青空文庫を検索して目的の作品を探すプログラムを作る
- 写真から顔を自動認識して、簡単に目隠し加工する(後編)
- Kinect v2のジェスチャーでBing Mapsを未来的に直感操作する
- 場所と写真を記録するプログラムを作って思い出のシーンを保存しよう
- 声で選んだアイテムをプレイヤーの身体に装着・連動させるKinectサンプル
- 画像に各種フィルタを適用して保存するWindowsアプリを作る
- お気に入りの写真に登場する、仲良しクラウディアちゃん