Help us understand the problem. What is going on with this article?

HUAWEI ML Kitを使用して、ID用写真のDIYアプレットを作成する方法

概要

以前の投稿で、HUAWEI ML Kitを使用したSmile-Cameraの作成方法を検討しました。今回は、HUAWEI ML Kitの新機能をご紹介します。

学校や会社からIDカード用に特定の背景色で撮影された1インチか2インチのポートレート写真を用意するよう頼まれたことはないでしょうか?多くの場合、そのような用途に適した写真は手元にないでしょう。以前、私が通っていた学校が個人用入室カードを学生のために申請する必要がありました。ところが、フォトスタジオは閉店していました。そこで私は、ベッドのシーツを背景にして、自分のスマートフォンを使い写真を撮りました。その結果、担任の先生から叱られる羽目になりました。しかし、HUAWEI ML Kitを使用すれば、画像分割SDKをアプリに統合して、ID用写真のDIYアプレットを開発し、このような問題を解決することができます。

さらに良いことに、このSDKは完全に無償であり、Android端末で動作します。

ID用写真のDIYアプレットの開発

1.準備

1.1 Huawei Mavenリポジトリをプロジェクトレベルのbuild.gradleファイルに追加する

Android Studioプロジェクトのルートディレクトリにあるbuild.gradleファイルを開きます。
1.png
このMavenリポジトリアドレスを追加します。

buildscript {
    repositories {        
        maven {url 'http://developer.huawei.com/repo/'}
    }    }allprojects {
    repositories {       
        maven { url 'http://developer.huawei.com/repo/'}
    }}

1.2 SDK依存関係をアプリレベルのbuild.gradleファイルに追加する

顔検出SDKとベースSDKをインポートします。

dependencies{ 
  // Import the base SDK. 
  implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' 
  // Import the face detection SDK. 
  implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:1.0.2.301'   }

1.3 自動モデルダウンロード機能をAndroidManifest.xmlファイルに追加する

アプリがHUAWEI AppGalleryからダウンロードされた際に、アプリの機械学習モデルが自動的に最新版に更新されるようにするには、以下の内容をAndroidManifest.xmlファイルに追加します。

<manifest    
   <application  
       <meta-data                     
           android:name="com.huawei.hms.ml.DEPENDENCY"          
           android:value= "imgseg "/>                 
   </application></manifest> 

1.4 AndroidManifest.xmlファイルでカメラとストレージの権限を適用する

<!--Storage permission --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2.コードの開発

2.1 動的な権限の申請を送信する

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (!allPermissionsGranted()) {
        getRuntimePermissions();
    }}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode != PERMISSION_REQUESTS) {
        return;
    }
    boolean isNeedShowDiag = false;
    for (int i = 0; i < permissions.length; i++) {
        if (permissions[i].equals(Manifest.permission.READ_EXTERNAL_STORAGE) && grantResults[i] != PackageManager.PERMISSION_GRANTED) {
            // If camera or storage permissions are unauthorized, an authorization dialog box will be displayed.
            isNeedShowDiag = true;
        }
    }
    if (isNeedShowDiag && !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setMessage(getString(R.string.camera_permission_rationale))
                .setPositiveButton(getString(R.string.settings), new DialogInterface.OnClickListener() {
                    @Override                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        intent.setData(Uri.parse("package:" + getPackageName())); // Open the corresponding settings page based on the package name.
                        startActivityForResult(intent, 200);
                        startActivity(intent);
                    }
                })
                .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).create();
        dialog.show();
    }}

2.2 画像分割分析機能を作成する

MLImageSegmentationSettingを使用して、画像分割分析機能を作成します。

MLImageSegmentationSetting setting = new MLImageSegmentationSetting.Factory()
                .setAnalyzerType(MLImageSegmentationSetting.BODY_SEG)
                .setExact(true)
                .create();        this.analyzer = MLAnalyzerFactory.getInstance().getImageSegmentationAnalyzer(setting);

2.3 android.graphics.Bitmapを使用してMLFrameオブジェクトを作成して、分析機能が画像を検出できるようにする

MLFrame mlFrame = new MLFrame.Creator().setBitmap(this.originBitmap).create();

2.4 asyncAnalyseFrameメソッドを呼び出して画面分割を実行する

// Create a task to process the results returned by the image segmentation analyzer.
Task<MLImageSegmentation> task = analyzer.asyncAnalyseFrame(frame); // Asynchronously process the results returned by the image segmentation analyzer. Task<MLImageSegmentation> task = this.analyzer.asyncAnalyseFrame(mlFrame);
            task.addOnSuccessListener(new OnSuccessListener<MLImageSegmentation>() {
                @Override                public void onSuccess(MLImageSegmentation mlImageSegmentationResults) {
                    // Transacting logic for segment success.
                    if (mlImageSegmentationResults != null) {
                        StillCutPhotoActivity.this.foreground = mlImageSegmentationResults.getForeground();
                        StillCutPhotoActivity.this.preview.setImageBitmap(StillCutPhotoActivity.this.foreground);
                        StillCutPhotoActivity.this.processedImage = ((BitmapDrawable) ((ImageView) StillCutPhotoActivity.this.preview).getDrawable()).getBitmap();
                        StillCutPhotoActivity.this.changeBackground();
                    } else {
                        StillCutPhotoActivity.this.displayFailure();
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override                public void onFailure(Exception e) {
                    // Transacting logic for segment failure.
                    StillCutPhotoActivity.this.displayFailure();
                    return;
                }
            });

2.5 画像の背景を変更する

this.backgroundBitmap = BitmapUtils.loadFromPath(StillCutPhotoActivity.this, id, targetedSize.first, targetedSize.second);BitmapDrawable drawable = new BitmapDrawable(backgroundBitmap);this.preview.setDrawingCacheEnabled(true);this.preview.setBackground(drawable);this.preview.setImageBitmap(this.foreground);this.processedImage = Bitmap.createBitmap(this.preview.getDrawingCache());this.preview.setDrawingCacheEnabled(false);

結果

以上で終わりです。ID用写真のDIYアプレットは使用可能です。早速、使ってみましょう。
20200321104442628.gif

ソースコードをGitHubアップロードしているので、機能の向上などお気軽にお試しください。コーディングスキルを強化したい場合、ポートレートをスーツに着せ替えるなどの機能を追加してみてはいかがでしょうか?
このID用写真のDIYアプレットを作成したように、画面分割機能を利用してあらゆる種類の便利な機能を持つアプリを作成することができます。例えば、以下のような機能が挙げられます。
1.ポートレートを切り取り、背景を変えることにより、ユーザーは面白い設定を色々と楽しんだり、ぼやけた画像を背景にして芸術的な写真を作成したりする。
2.画像内で空、植物、食品、猫、犬、花、水、砂、建物、山を識別して修正する。ユーザーが空をより青くしたり、水をより透明にしたりして写真を改善したいと思う場合、このような機能が役に立ちます。
3.ビデオストリーム内でオブジェクトを認識したり、ビデオストリームの背景を編集・変更したりする。
詳しくは、当社の公式ウェブサイトをご覧ください。

近日公開予定

さらに実用的な場面でHUAWEI ML Kitをお使いいただけるようになります。ワクワクするような内容に是非ご注目ください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした