零基础开发AI应用--华为HiAI的应用

最近在学习ai,了解到了华为HiAI这么一个app开发神器。他是华为对外开放的一套AI工具,包含SDK,IDE,用户指南等。能帮助小白用户迅速开发出ai应用,而且能用上华为手机的NPU能力,性能对比CPU提升不少。

目前已经开放出来的API包含人脸检测、人脸对比、图像超分、美学评分、码识别、分词、意图识别、语音识别等等。详细的介绍可以上华为的开发者联盟看看。http://developer.huawei.com/consumer/cn/devservice/doc/31403

这里介绍下学习的过程,拿人脸检测做一个简单的demo。

1、首先下载IDE,其实就是一个Android studio的插件,不过对于开发HiAI应用来说十分方便。下载地址:http://developer.huawei.com/consumer/cn/devservice/doc/3141902

2、安装完成之后,打开插件,效果是这样的。

可以看到API的介绍,代码示例。比较方便的是,代码可以用鼠标拖到到自己工程的java代码里,插件同时也会把需要的SDK复制到工程lib目录下,并改写gradle配置。这个功能不错。

3、开始编码,我写了一个简单的例子,选择一张相册的图片,然后调用人脸识别API,把识别出来的人脸框出来。

需要注意的是,调用人脸检测API的操作不能放在工作线程中,否则会报错。

本文源码在文末。。。

4、调试,说到调试就不得不提起IDE的一个强大功能,远程真机。这对于买不起p20的码农来说无异于雪中送炭,调试当然要选最贵的机型。效果如图,不过缺点就是比本地真机要慢一些,看在这么多免费机型的份上也就忍了。另外,使用真机需要注册一个华为开发者账号。

人脸检测的速度还是很快的,看来NPU对于ai的加成还是很不错的。

以下为demo源码

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="人脸检测"/>
    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="选择图片"/>

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="400dp"/>
</LinearLayout>
MainActivity.java
package com.hiai.face;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.huawei.hiai.vision.common.ConnectionCallback;
import com.huawei.hiai.vision.common.VisionBase;
import com.huawei.hiai.vision.visionkit.common.BoundingBox;
import com.huawei.hiai.vision.visionkit.face.Face;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_STORE_PERMISSION = 1;
    private static final int REQUEST_CHOOSE_PHOTO = 2;

    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = findViewById(R.id.img);

        /** 应用VisionBase静态类进行初始化,异步拿到服务的连接*/
        VisionBase.init(this, new ConnectionCallback() {
            @Override
            public void onServiceConnect() {
                /** 这个回调方法在服务连接成功时被调用; 您可以执行探测器类的初始化,标记服务连接状态等*/
            }

            @Override
            public void onServiceDisconnect() {
                /** 当服务断开时,调用此回调方法; 您可以选择在此重新连接服务,或者处理异常*/
            }
        });

        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (ContextCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                            REQUEST_STORE_PERMISSION);
                } else {
                    choosePhoto();
                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_STORE_PERMISSION) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                choosePhoto();
            } else {
                Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (resultCode == RESULT_OK && requestCode == REQUEST_CHOOSE_PHOTO) {

            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            final String imgPath = cursor.getString(columnIndex);
            cursor.close();
            Bitmap bitmap = BitmapFactory.decodeFile(imgPath);
            imageView.setImageBitmap(bitmap);

            new FaceDetectTask(new FaceDetectTask.FaceDetectListener() {
                @Override
                public void onDetectFinish(List<Face> faces) {
                    if (faces != null && !faces.isEmpty()) {
                        drawFace(imgPath, faces);
                    }
                }
            }).execute(bitmap);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    private void choosePhoto() {
        Intent intent = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, REQUEST_CHOOSE_PHOTO);
    }

    private void drawFace(String imgPath, List<Face> faces) {
        Bitmap bitmap = BitmapFactory.decodeFile(imgPath).copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(3);
        for (Face face : faces) {
            BoundingBox faceRect = face.getFaceRect();
            canvas.drawRect(faceRect.getLeft(), faceRect.getTop(), faceRect.getLeft() + faceRect.getWidth(),
                    faceRect.getTop() + faceRect.getHeight(), paint);
        }
        imageView.setImageBitmap(bitmap);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        /** 释放资源*/
        VisionBase.destroy();
    }
}
FaceDetectTask.java
package com.hiai.face;

import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.Log;

import com.huawei.hiai.vision.face.FaceDetector;
import com.huawei.hiai.vision.visionkit.common.Frame;
import com.huawei.hiai.vision.visionkit.face.Face;

import org.json.JSONObject;

import java.util.List;

public class FaceDetectTask extends AsyncTask<Bitmap, Void, List<Face>> {

    private static final String LOG_TAG = "face_detect";
    private FaceDetectListener listener;

    public FaceDetectTask(FaceDetectListener listener) {
        this.listener = listener;
    }

    @Override
    protected List<Face> doInBackground(Bitmap... bitmaps) {
        Log.i(LOG_TAG, "init FaceDetector");
        FaceDetector faceDetector = new FaceDetector(null);
        Frame frame = new Frame();
        frame.setBitmap(bitmaps[0]);
        long l = System.currentTimeMillis();
        JSONObject jsonObject = faceDetector.detect(frame,null);
        Log.i(LOG_TAG, String.format("face detect: %s, cost: %d ms", jsonObject.toString(), System.currentTimeMillis() - l));
        List<Face> faces = faceDetector.convertResult(jsonObject);
        return faces;
    }

    @Override
    protected void onPostExecute(List<Face> faces) {
        listener.onDetectFinish(faces);
        super.onPostExecute(faces);
    }

    public interface FaceDetectListener {
        void onDetectFinish(List<Face> faces);
    }
}

最后,加上浏览相册的权限

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

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值