tonkunの備忘録

色々調べた事、試した事などを載せます

Xamarin.Android Google Play Services Visionを使ってみた(顔認識)

前回からだいぶ時間が経ってしまいましたが、

tonkun-no.hatenablog.com

今回は顔認識を試してみました。

殆ど、サンプル通りに作っていますが、ソースはGitHubにあります。

XamarinSamples/VisionFacesSample.Android at master · tonkun-no/XamarinSamples · GitHub

インストールや設定等は前回と同じです。

FaceTrackerActivity(抜粋)
protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.FaceTracker);
    _cameraSourcePreview = FindViewById<CameraSourcePreview>(Resource.Id.cameraSourcePreview);
    _overlay = FindViewById<GraphicOverlay>(Resource.Id.faceOverlay);
    var detector = new FaceDetector.Builder(Application.Context)
        //.SetTrackingEnabled(false)
        .SetLandmarkType(LandmarkDetectionType.All)
        .SetMode(FaceDetectionMode.Accurate)
        .Build();
    detector.SetProcessor(
        new MultiProcessor.Builder(new FaceTrackerFactory(_overlay)).Build());

    _cameraSource = new CameraSource.Builder(this, detector)
        .SetAutoFocusEnabled(true)
        //.SetRequestedPreviewSize(640, 480)
        .SetFacing(CameraFacing.Front)
        .SetRequestedFps(30.0f)
        .Build();
}

今回は顔認識なのでFaceDetectorを使っています。

顔認識したタイミングでバーコードの時と同じようにTrackerクラスのOnNewItemメソッドが実行されています。
後はそのタイミングで、顔部分に表示するためのクラスを生成して、都度描画している感じです。

ビルドして実行すると、無事顔認識ができました。 カメラを横にするとプレビューサイズがおかしくなるのは、どこか間違ってるんだとは思いますが・・・ご容赦を。

f:id:tonkun_no:20161024034743p:plain

本当にやってみたかった事はこの先なんですが、また出来たら書こうと思います。

ASP.NET Identityを使ったメール認証でのtokenの有効期限の変更方法

仕事でユーザ登録時にASP.NET Identityを使ったメール認証を使用したのですが、 tokenに有効期限があるとは知らずに1日後にあっさりtokenの有効期限が切れて焦ったので変更方法のメモ。

ASP.NET MVC 5のテンプレプロジェクトだと IdentityConfig.csファイル

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
{
・・・中略
    var dataProtectionProvider = options.DataProtectionProvider;
    if (dataProtectionProvider != null)
    {
        manager.UserTokenProvider = 
            new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"))
                { TokenLifespan = TimeSpan.FromDays(7)}; -- ここで日数指定
    }

恥ずかしながら無期限だと思ってました( ゚Д゚)

Xamarin.Android Google Play Services Visionを使ってみた

スキャナを作ってみようと色々調べていたらAndroid5.0以降はCameraクラスは非推奨との事で、 Camera2で試してみようかとも思ったんですが、Google Play Services Visionを使ってもできるようなので試しに使ってみました。

Google Play Services - Vision / Components / Xamarin

インストール

NugetからXamarin.GooglePlayServices.Visionをインストール。

f:id:tonkun_no:20160908020154p:plain

Manifest設定

プロジェクトのプロパティのから CAMERA をチェックオン

f:id:tonkun_no:20160908020618p:plain

実装

以下を参考に実装していきます。

com.google.android.gms.vision  |  Google APIs for Android  |  Google Developers

画面にはSurfaceViewを配置し、 MainActivityにはISurfaceHolderCallbackインターフェースも実装します。

MainActivity(抜粋)
protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);
    this.surfaceView = (SurfaceView)this.FindViewById(Resource.Id.surfaceview);
    this.surfaceView.Holder.AddCallback(this);

    // バーコードの種類を指定する場合はSetBarcodeFormatsで指定
    //BarcodeDetector detector = new BarcodeDetector.Builder(this).SetBarcodeFormats(BarcodeFormat.QrCode).Build();
    BarcodeDetector detector = new BarcodeDetector.Builder(this).Build();
    detector.SetProcessor(
        new MultiProcessor.Builder(new MyTrackerFactory(this.HandleScanResult)).Build());
    this.cameraSource = new CameraSource.Builder(this, detector).SetFacing(CameraFacing.Back).SetAutoFocusEnabled(true).Build();
}

public void HandleScanResult(Barcode item)
{
    string msg = string.Empty;
    if (item != null && !string.IsNullOrEmpty(item.RawValue))
        msg = "Found Barcode: " + item.RawValue;
    else
        msg = "Scanning Canceled";
    this.RunOnUiThread(() => Toast.MakeText(this, msg, ToastLength.Long).Show());
}

public void SurfaceCreated(ISurfaceHolder holder)
{
    this.cameraSource.Start(this.surfaceView.Holder);
}
MyTrackerFactoryとBarcodeTracker
public class MyTrackerFactory
    : Java.Lang.Object, MultiProcessor.IFactory
{
    Action<Barcode> handleScanAction;
    public MyTrackerFactory(Action<Barcode> action)
    {
        this.handleScanAction = action;
    }
    public Tracker Create(Java.Lang.Object item)
    {
        return new BarcodeTracker(handleScanAction);
    }
}

public class BarcodeTracker
    : Tracker
{
    Action<Barcode> handleScanAction;
    public BarcodeTracker(Action<Barcode> action)
    {
        this.handleScanAction = action;
    }
    public override void OnNewItem(int id, Java.Lang.Object item)
    {
        handleScanAction((Barcode)item);
    }
}

バーコード読み込み時の処理をMainActivityで記述している為、
どうにかBarcodeTrackerに渡したくて無理やり渡しています。

今回はサンプルなので良いですが、実際にこれを使って実装する場合は 全体的にどう実装するんだろう?
個人的にはついついISurfaceHolderCallbackを実装したなんたらmanagerクラスを作って、やってしまいそうです( ゚Д゚)*1

ビルドして実行すると、無事バーコードの読み込みが出来ました。 f:id:tonkun_no:20160908215221p:plain

Visionは他の機能もあるので試してみようかと思います。

*1:そして役割が増えていく・・・

Xamarin Tシャツをもらおう その後

前回の記事のその後です。

tonkun-no.hatenablog.com

動画を投稿してからその後、田淵さんのツイートを見るとTシャツの連絡が来たそうです。

それから数日待ってみましたが、何の連絡も来なかったので「むーこれは外れたかなぁ」と思っていると

@nuits_jpさんの気になるツイートが、

参考に直接問い合わせをしてみました。

なんか変な英語の気もしますが、そこは気にしない・・・

待つこと数時間、あっさり返信が来ました・・・orz f:id:tonkun_no:20160803032928p:plain

指定されたアドレスに移動してみると、名前や送信先の住所やTシャツのサイズを入力するフォームでした。 なんだか英語で住所書くのってドキドキしませんか(笑)

アメリカのTシャツは1サイズ大きいらしいのでMを指定しました。 結果に3週間ほどかかるそうですが、無事Tシャツが届くのを待ちたいと思います(‘ω‘ )

のんびり待てば連絡は来たのかもしれませんが、精神的に待ってるのは辛かったので・・・ @nuits_jpさんに感謝です。

Xamarin Tシャツをもらおう

田淵さんのblogでXamarin でアプリコンテストが紹介されていました。

ytabuchi.hatenablog.com

Azure Easy Tablesを使ったXamarinのアプリを動画でツイートすると、 憧れのXamarin T-シャツがもらえるそうです。
全員がもらえるのかどうかは良くわかりませんが、もらえると信じて作ってみました。

以下のサイトを参考にさせてもらっています。 *1

nuits.hatenadiary.jp

ytabuchi.hatenablog.com

Azureのアカウントを作っているのが前提です。

Mobile Apps Quickstartにアクセス azure.microsoft.com

[Create Web App]をクリック f:id:tonkun_no:20160719003541p:plain

[アプリ名]、[リソースグループ]を入力して[App Service プラン/場所]をクリック f:id:tonkun_no:20160719004503p:plain

[新規作成]をクリック f:id:tonkun_no:20160719004604p:plain

[価格レベル]をクリック

f:id:tonkun_no:20160719010020p:plain

[全てを表示]をクリックする。そうしないとF1 Freeが表示されない(ずるい笑) f:id:tonkun_no:20160719010209p:plain

[F1 Free]をクリックして[選択]ボタンをクリック f:id:tonkun_no:20160719010447p:plain

[App Service]画面で[OK]をクリック [Web App]画面の[作成]ボタンをクリックするとデプロイが始まる(数分かかります) f:id:tonkun_no:20160719011023p:plain

デプロイが終わたら作成されたアプリをクリック f:id:tonkun_no:20160719011341p:plain

[設定]画面から[クイックスタート]を選択、[Xamarin.Android]を選択
※言語は自分のお好みでどうぞ f:id:tonkun_no:20160719011538p:plain

[Download]をクリックするとサンプルプロジェクトがダウンロードされる f:id:tonkun_no:20160719011934p:plain

あとはサンプルプロジェクトをVisual Studioで開いて、デバック実行するだけです。 f:id:tonkun_no:20160719012200p:plain

すごい・・簡単にできました( ゚Д゚)

[Easy Tables]から[todoitem]を見ると、データが登録されているのが分かります。 f:id:tonkun_no:20160719012556p:plain

これをタグ付きでツイートすればTシャツゲット?なんでしょうかね(‘ω‘ )

*1:と言うかほとんどそのままです・・・orz

Xamarin.Android ZXing.Net Mobileを使ってみた

簡単にスキャナが作れると言うことで、ZXing.Net Mobileを使ってみました。

https://github.com/Redth/ZXing.Net.Mobile

こちらにあるSampleコードとほとんど同じです。

インストール

NuGetからZXing.Net.Mobileをインストール

f:id:tonkun_no:20160703013331p:plain

Manifest設定

プロジェクトのプロパティの[Android Manifest]から [Required permissions]で
CAMERA
FLASHLIGHT
をチェックオン

f:id:tonkun_no:20160703014211p:plain

画面レイアウト

サンプルはいくつかボタンがありますが、取りあえず標準動作と思われる物のボタンのみ配置

f:id:tonkun_no:20160703015128p:plain

MainActivity

以下のように記載

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);
    var scanner = new MobileBarcodeScanner();
    // Resource取得
    var buttonScanDefaultView = this.FindViewById<Button>(Resource.Id.buttonScanDefaultView);
    // Clickイベント設定
    buttonScanDefaultView.Click += async (sender, e) =>
    {
        scanner.UseCustomOverlay = false;
        scanner.TopText = "Hold the camera up to the barcode";
        scanner.BottomText = "Wait for the barcode to automatically scan!";
        var result = await scanner.Scan();
        HandleScanResult(result);
    };
}

/// <summary>
/// 読み込み結果に対する処理
/// </summary>
/// <param name="result"></param>
public void HandleScanResult(ZXing.Result result)
{
    string msg = string.Empty;
    if (result != null && !string.IsNullOrEmpty(result.Text))
        msg = "Found Barcode: " + result.Text;
    else
        msg = "Scanning Canceled";
    this.RunOnUiThread(() => Toast.MakeText(this, msg, ToastLength.Short).Show());
}

ビルドして実行・・・

f:id:tonkun_no:20160703020400p:plain

f:id:tonkun_no:20160703020507p:plain

f:id:tonkun_no:20160703020533p:plain

認識早いですね。こりゃ便利。 他の機能も試してみようと思います(・ω・)ノ

不明点

Runtime Permissionの設定方法が良くわかりません・・・
ZXing.Net.Mobile.Formsの場合は、以下の内容で良いらしいですが。

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);           
}

Xamarin.Android 各種Layoutについて

デザイナでツールボックスを見てると、Layoutがいくつもあって良くわからなかったので調べた内容のメモです。

LinearLayout(Horizontal)

LinearLayout(Vertical)

GridLayout(Vertical)

  • コントロールが指定した列数で格子状に並べられる。

  • 行をまたがってコントロールを配置できるらしい(やり方が良くわからず未確認)

TableLayout

  • 行単位でTableRowと言うコントロールがあり、そこに配置したいコントロールを並べる。 行をまたがってコントロールを配置する必要がないのであれば、こちらの方が使いやすそう。

RelativeLayout

  • コントロールに対して相対的な位置を指定して配置できる。 このButtonは画面右上とか、とあるButtonの右と言った指定が可能なので、うまく使えば複雑なレイアウトが作れそう。

  • デザイナから画面にコントロールを置くのが難しかった・・・(絶妙な場所にドラック&ドロップしないと配置できなかった)

これまではWindows Formでの開発がメインだったので、 同じように好きな場所にポイポイコントロールを配置できるのかと思っていました。 慣れるまでは画面レイアウトの作成が大変そうです。