表情包斗图,作为人生新晋一大乐事,曾经是宽广网友每天必经的聊天互动环节。什么哄堂大笑、满腹槽点、彻底无语……这些万千语言无奈贴切形容的情绪细节,总能被一张看似平平无奇的表情包完满形容,堪称一图胜千言,四两拨千斤!

现在,在表情包斗图进入白热化阶段,人们对表情包的定制化需要日益增多,人人是表情包的搬运工,人人也是后劲热图的创造者!赋予集体制作个性化表情包的能力很有必要。应用机器学习的图像宰割性能,轻松宰割简单图片背景,让表情包制作简略而高效,让咱们来看看如何将一张图片变成传情达意的表情包吧!

开发筹备

Maven仓和SDK的配置步骤能够参考开发者网站中的利用开发介绍

https://developer.huawei.com/...

配置集成的SDK包

图像宰割提供了两种SDK集成形式,一种是事后将宰割算法包事后集成在利用中,另一种是在利用装置运行后,再将所需的算法包下载到利用中,能够依据利用的应用场景和所需成果进行抉择。
本文是应用了Full SDK的集成计划,在利用的build.gradle文件中,dependencies内增加图像宰割的SDK依赖

implementation 'com.huawei.hms:ml-computer-vision-segmentation:2.2.0.300'implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:2.2.0.300'

配置AndroidManifest.xml

关上main文件夹中的AndroidManifest.xml文件,能够依据场景和应用须要,配置读取和写入手机存储的权限,在<application>前增加

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

在<application>内增加如下语句,当利用装置后,会自动更新最新的机器学习模型到设施

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

开发步骤

配置存储权限申请

手机的存储权限,除了在Manifest中申明,还须要在Activity中进行动静申请。
在MainActivity的onCreate()办法中,调用requestPermission办法,对WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE权限进行申请

protected void onCreate(Bundle savedInstanceState) {    ……    requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE);    requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);……}

requestPermission办法的实现如下,首先对权限进行判断,如果未获取权限,则进行申请,如果曾经获取了,则返回

private void requestPermission(String permisssions) {    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {        return;    }            if (ContextCompat.checkSelfPermission(this, permisssions)            != PackageManager.PERMISSION_GRANTED) {        ActivityCompat.requestPermissions(this, new String[]{permisssions}, REQUEST_CODE);    } else {        return;    }}

读取相册中的图片

咱们先从相册中选取要进行表情包制作的图片,在xml文件中创立一个按钮chooseImg,点击后调用selectLocalImage办法

this.relativeLayoutLoadPhoto = this.findViewById(R.id.chooseImg);this.relativeLayoutLoadPhoto.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) { MainActivity.this.selectLocalImage(StillCutPhotoActivity.this.REQUEST_CHOOSE_ORIGINPIC);    }});

selectLocalImage办法的实现如下

private void selectLocalImage(int requestCode) {    Intent intent = new Intent(Intent.ACTION_PICK, null);    intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");    this.startActivityForResult(intent, requestCode);}

进行图像宰割制作表情包

再创立一个按钮cut,点击后调用createImageTransactor办法,进行图像宰割分析器的创立

this.relativeLayoutCut = this.findViewById(R.id.cut);this.relativeLayoutCut.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        if (MainActivity.this.imageUri == null) {            Toast.makeText(MainActivity.this.getApplicationContext(), R.string.please_select_picture, Toast.LENGTH_SHORT).show();        } else {            MainActivity.this.createImageTransactor();            Toast.makeText(MainActivity.this.getApplicationContext(), R.string.cut_success, Toast.LENGTH_SHORT).show();        }    }});

在createImageTransactor办法中,咱们首先创立一个图像宰割的分析器,再进行分析器的配置,将其设置为人像宰割模式

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

从相册中选取的文件,通过imageUri,将其关上为Bitmap格局

Pair<Integer, Integer> targetedSize = this.getTargetSize();int targetWidth = targetedSize.first;int targetHeight = targetedSize.second;this.originBitmap = BitmapUtils.loadFromPath(StillCutPhotoActivity.this, this.imageUri, targetWidth, targetHeight);

之后创立MLFrame,调用asyncAnalyseFrame进行异步图像宰割解决

MLFrame mlFrame = new MLFrame.Creator().setBitmap(this.originBitmap).create();Task<MLImageSegmentation> task = this.analyzer.asyncAnalyseFrame(mlFrame);

图像宰割实现后,对返回的后果进行解决,将去除背景后的图像保留到processedImage中

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();        } else {            StillCutPhotoActivity.this.displayFailure();        }    }}).addOnFailureListener(new OnFailureListener() {    @Override    public void onFailure(Exception e) {        // Transacting logic for segment failure.        StillCutPhotoActivity.this.displayFailure();        return;    }});

保留表情包

最初将解决好的图像转换成png格局,存储到零碎相册中

public void saveToAlbum(Bitmap bitmap){    File file = null;    String fileName = System.currentTimeMillis() +".png";    File root = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), this.context.getPackageName());    File dir = new File(root, "image");    if(dir.mkdirs() || dir.isDirectory()){        file = new File(dir, fileName);    }    FileOutputStream os = null;    try {        os = new FileOutputStream(file);        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);        os.flush();    } catch (FileNotFoundException e) {        Log.e(TAG, e.getMessage());    } catch (IOException e) {        Log.e(TAG, e.getMessage());    }finally {        try {            if(os != null) {                os.close();            }        }catch (IOException e){            Log.e(TAG, e.getMessage());        }    }    if(file == null){        return;    }    if(imageUtilCallBack != null) {        try {            imageUtilCallBack.callSavePath(file.getCanonicalPath());        } catch (IOException e) {            Log.e(TAG, e.getMessage());        }    }    // Gallery refresh.    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {        String path = null;        try {            path = file.getCanonicalPath();        } catch (IOException e) {            Log.e(TAG, e.getMessage());                        }        MediaScannerConnection.scanFile(this.context, new String[]{path}, null,                new MediaScannerConnection.OnScanCompletedListener() {                    @Override                    public void onScanCompleted(String path, Uri uri) {                        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);                        mediaScanIntent.setData(uri);                        ImageUtils.this.context.sendBroadcast(mediaScanIntent);                    }                });    } else {        String relationDir = file.getParent();        File file1 = new File(relationDir);        this.context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(file1.getAbsoluteFile())));    }}

成果示例

编译运行后,能够从相册中抉择想要制作表情包的照片,点击Cut,ML Kit会实现之后的人像辨认和图像宰割步骤,将芜杂的背景去除,返回人像的图片,之后点击Save即可将其保留为没有背景的表情包。

保留后即可将表情包增加到社交软件中啦,快来试试吧!

理解更多相干内容
拜访华为机器学习图像宰割服务官网

获取华为机器学习服务开发领导文档

华为HMS Core官方论坛

华为机器学习开源仓地址:GitHub、Gitee

解决集成问题请到Stack Overflow

点击关注,第一工夫理解HMS Core最新技术~