讯飞人脸识别

来源:互联网 发布:php程序员桌面壁纸 编辑:程序博客网 时间:2024/04/28 10:42

今天做了一套二级Java题,直接就绝望了。选择题就得了25分,错了将近一半,大后天就考了,忐忑。。


前天晚上和大前天晚上加班写了一个讯飞的一个人脸识别,结果昨天电脑系统让我安装Linux按的系统炸了。去他的,按了一下午系统昨天晚上干到十二点又写了一遍,不仅写的时间缩短了,而且更加清楚套路了。


整体来看,大约分以下步骤进行写。

1.从官网上申请服务,会给你个id也就是访问的key。吧这个记下来,下载人脸识别的SDK包括两个jar,和几个二进制文件。SDk里面有例程,导入Eclipce中运行无误后就可以看结构仿写了。


2.因为是用Android Studio写的所以较麻烦,需要将jar文件和so文件放入正确的位置。


3.主要分为两个类写的,第一个类就是进行照完的人脸进行裁剪类,这个是使用android自带的裁剪器,进行相应的配置,这个类里面主要是裁剪,对摄影的角度的判断,旋转图片,保存图片这几个方法。


4.第二个类就是通过SDK类进行识别了,首先需要将自己的申请的key在初始化SDK的时候添加进去,作为App唯一的标志允许访问服务,这个类主要是分三大块:Button的监听、对返回的数据进行Json解析判断、对Intent的监听(主要是照完相后对图片进行裁剪)。


一、下载的jar so文件的处理


新建jniLibs文件夹放入so文件    将Msc.jar Sunflower.jar文件放入libs文件夹中并添加进编译路径。


    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.READ_PHONE_STATE" />    <uses-permission android:name="android.permission.CAMERA" />    <uses-permission android:name="android.permission.WRITE_SETTINGS" />    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    <uses-feature android:name="android.hardware.camera" />    <uses-feature android:name="android.hardware.camera.autofocus" />

二、裁剪类

package com.example.hejingzhou.facerecognition;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.Matrix;import android.media.ExifInterface;import android.net.Uri;import android.os.Environment;import android.provider.MediaStore;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;/** * Created by Hejingzhou on 2016/3/22. */public class HeadTrim {    public final static int REQUEST_PICTURE_CHOOSE = 1;    public final static int REQUEST_CAMERA_IMAGE = 2;    public final static int REQUEST_CROP_IMAGE = 3;    /**     * 裁剪图片  android自带的裁剪     * @param activity     * @param uri     */    public static void corpPicture(Activity activity,Uri uri){        Intent innerIntent = new Intent("com.android.camera.action.CROP");//启用自带裁剪        innerIntent.setDataAndType(uri, "image/*");        innerIntent.putExtra("crop", "ture");//裁剪小正方形,不然没有裁剪功能,只能选取        innerIntent.putExtra("aspectX", 1);//放大缩小缩放比例        innerIntent.putExtra("aspectY", 1);//缩放比例 1  :1        innerIntent.putExtra("outputX", 320);        innerIntent.putExtra("outputY", 320);//限制图片大小        innerIntent.putExtra("return-data",true);        //切图大小不足 320 会出现黑框,防止出现黑框并输出        innerIntent.putExtra("scale",true);        innerIntent.putExtra("scaleUpIfNeeded",true);        File imageFile = new File(getImagePath(activity.getApplicationContext()));//从这个文件路径创建文件        innerIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(imageFile));        //MediaStore.EXTRA_OUTPUT  表示内容解析器被用来存储请求的Uri的图像或视频        innerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//带上裁剪好的图片传递出去        activity.startActivityForResult(innerIntent,REQUEST_CROP_IMAGE);    }    /**     * 获取裁剪的图片路径     * @param context     * @return     */    public static String getImagePath(Context context){        String path;        if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){        //如果当前存储的状态 是 不能挂载和读写的            path = context.getFilesDir().getAbsolutePath();//路径就等于这个文件的绝对路径(从根开始)        }else {            path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/msc/";        }        if(!path.endsWith("/")){ //与路径的最后一个字符进行比较如果不是“/”那么就添加“/”            path += "/";        }        File folder = new File(path);        if(folder != null && !folder.exists()){//如果文件不为空 或者不存在,创建这个文件的文件夹            folder.mkdirs();        }        path += "ifd.jpg";        return path;    }    /**     * 读取图片的属性   :的角度     * @param path     * @return     */    public static int readPictureDegree(String path){        int degree = 0;//度        try {            ExifInterface exifInterface = new ExifInterface(path);//阅读和写作在JPEG文件的Exif标记类            int orientation  = exifInterface.getAttributeInt(            //ExifInterface.getAttributeInt 返回指定标记的整数值                    ExifInterface.TAG_ORIENTATION,                    ExifInterface.ORIENTATION_NORMAL);//方向常规            switch (orientation){                case ExifInterface.ORIENTATION_ROTATE_90:                    degree = 90;                    break;                case ExifInterface.ORIENTATION_ROTATE_180:                    degree = 180;                    break;                case ExifInterface.ORIENTATION_ROTATE_270:                    degree = 270;                    break;            }        } catch (IOException e) {            e.printStackTrace();        }        return degree;    }    /**     * 旋转图片     * @param angle  旋转角度     * @param bitmap  原图     * @return 旋转后的  bitmap     */    public static Bitmap rotateImage(int angle,Bitmap bitmap){        Matrix matrix = new Matrix();        matrix.postRotate(angle);   //postconcats与指定的旋转矩阵        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);        /**         * createBitmap  返回一个不可变的位图从源位图的子集         * @param source   The bitmap we are subsetting         * @param x        The x coordinate of the first pixel in source         * @param y        The y coordinate of the first pixel in source         * @param width    The number of pixels in each row         * @param height   The number of rows         * @param m        Optional matrix to be applied to the pixels   可选的矩阵应用到像素         * @param filter   true if the source should be filtered.        如果源应筛选,true         *                   Only applies if the matrix contains more than just         *                   translation.         */        return resizedBitmap;    }    /**     * 保存图片     * @param context     * @param bitmap     */    public static void saveBitmapToFile(Context context, Bitmap bitmap) {        String file_path = getImagePath(context);        File file = new File(file_path);        FileOutputStream fileOutputStream;        try {            fileOutputStream = new FileOutputStream(file);            bitmap.compress(Bitmap.CompressFormat.JPEG,85,fileOutputStream);            fileOutputStream.flush();            fileOutputStream.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}


这个类中的裁剪方法挺好的,记住在别处也会用的着。


三、校验登陆(千万不能忘了初始化SDK并加入自己的key和实例化FaceRequest)

<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">package com.example.hejingzhou.facerecognition;</span>

<span style="font-family: Arial, Helvetica, sans-serif;">import android.app.ProgressDialog;</span>
import android.content.DialogInterface;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Rect;import android.media.MediaScannerConnection;import android.net.Uri;import android.os.Environment;import android.provider.MediaStore;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.view.WindowManager;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.Toast;import com.iflytek.cloud.ErrorCode;import com.iflytek.cloud.FaceRequest;import com.iflytek.cloud.RequestListener;import com.iflytek.cloud.SpeechConstant;import com.iflytek.cloud.SpeechError;import com.iflytek.cloud.SpeechUtility;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.UnsupportedEncodingException;import java.util.Currency;public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private String TAG = getClass().getCanonicalName();    private final int REQUEST_PICTURE_CHOOSE = 1;    private final int REQUEST_CAMERA_IMAGES = 2;    private FaceRequest faceRequest;    private Toast toast;    private byte[] imageData = null;    private Bitmap image = null;    private EditText editTextUserPassword;    private String UserPassword;    private ProgressDialog progressDialog;    private File pictureFile;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init() {        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);        SpeechUtility.createUtility(this, "appid=" + getString(R.string.app_key));//初始化SDK 千万不能忘记写appid后边的等号  id是自己其官网上申请的        //忘记会报 10274无效 key        faceRequest = new FaceRequest(this);        findViewById();        toast = Toast.makeText(this,"",Toast.LENGTH_SHORT);        progressDialog = new ProgressDialog(this);        progressDialog.setCancelable(true);//设置是否可取消        progressDialog.setTitle("请稍等...");        progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {            @Override            public void onCancel(DialogInterface dialog) {                if (null != faceRequest) {                    faceRequest.cancel();                }            }        });    }    private void findViewById() {        editTextUserPassword = (EditText)findViewById(R.id.editTextUserPassword);        findViewById(R.id.buttonRegister).setOnClickListener(MainActivity.this);        findViewById(R.id.buttonPicture).setOnClickListener(MainActivity.this);        findViewById(R.id.buttonVerification).setOnClickListener(MainActivity.this);        findViewById(R.id.imageViewHead).setOnClickListener(MainActivity.this);    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.buttonPicture:                pictureFile = new File(Environment.getExternalStorageDirectory(),                        "picture"+System.currentTimeMillis()/1000+".jpg");                Intent picIntent = new Intent();                picIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);                picIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(pictureFile));                picIntent.putExtra(MediaStore.Images.Media.ORIENTATION,0);                startActivityForResult(picIntent,REQUEST_CAMERA_IMAGES);                break;            case R.id.buttonRegister:                UserPassword = ((EditText)findViewById(R.id.editTextUserPassword)).getText().toString();                if(TextUtils.isEmpty(UserPassword)){                    showToast("请输入您的密钥");                    return;                }else if(null != imageData){                    progressDialog.setMessage("注册中...");                    progressDialog.show();                    faceRequest.setParameter(SpeechConstant.AUTH_ID, UserPassword);//将授权标识和密码上传服务器记录                    faceRequest.setParameter(SpeechConstant.WFR_SST,"reg");//业务类型train Or verify                    faceRequest.sendRequest(imageData,requestListener);                }else showToast("请先进行图像拍摄...");                break;            case R.id.buttonVerification:                UserPassword = ((EditText)findViewById(R.id.editTextUserPassword)).getText().toString();                if(TextUtils.isEmpty(UserPassword)){                    showToast("密钥不能为空哦...");                }else if(imageData != null){                    progressDialog.setMessage("验证中,请稍等...");                    progressDialog.show();//6--12字符 不能以数字开头                    faceRequest.setParameter(SpeechConstant.AUTH_ID, UserPassword);                    faceRequest.setParameter(SpeechConstant.WFR_SST,"verify");                    faceRequest.sendRequest(imageData,requestListener);                }else showToast("请先捕捉头像...");                break;        }    }    /**     * 处理拍完照后,跳转到裁剪界面     * @param requestCode     * @param resultCode     * @param data     */    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        Log.i(TAG, "运行到了onActivityResult");        if(resultCode != RESULT_OK){            Log.i(TAG,"requestCode未成功");            return;        }        String fileSrc = null;        if(requestCode == REQUEST_PICTURE_CHOOSE){            if("file".equals(data.getData().getScheme())){                fileSrc = data.getData().getPath();                Log.i(TAG,"file "+fileSrc);            }else {                String[] proj = {MediaStore.Images.Media.DATA};                Cursor cursor = getContentResolver().query(data.getData(), proj, null, null, null);                cursor.moveToFirst();                int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);                fileSrc = cursor.getString(idx);                cursor.close();            }            HeadTrim.corpPicture(this, Uri.fromFile(new File(fileSrc)));        }else if(requestCode == REQUEST_CAMERA_IMAGES){            if(null == pictureFile){                showToast("拍照失败,请重试...");                return;            }            fileSrc = pictureFile.getAbsolutePath();            updataGallery(fileSrc);            HeadTrim.corpPicture(this,Uri.fromFile(new File(fileSrc)));        }else if(requestCode == HeadTrim.REQUEST_CROP_IMAGE){            Bitmap bitmap = data.getParcelableExtra("data");            Log.i(TAG,"bitmp是否为空");            if(null != bitmap){                HeadTrim.saveBitmapToFile(MainActivity.this,bitmap);            }            fileSrc = HeadTrim.getImagePath(MainActivity.this);//获取图片保存路径            BitmapFactory.Options options = new BitmapFactory.Options();            options.inJustDecodeBounds = true;            image = BitmapFactory.decodeFile(fileSrc,options);            options.inSampleSize = Math.max(1, (int) Math.ceil(Math.max(                    (double) options.outWidth / 1024f,                    (double) options.outHeight / 1024f            )));            options.inJustDecodeBounds = false;            image = BitmapFactory.decodeFile(fileSrc,options);            //如果imageBitmap 为空图片不能正常获取            if(null == image){                showToast("图片信息无法正常获取");                return;            }            int degree = HeadTrim.readPictureDegree(fileSrc);            if(degree != 0){                image = HeadTrim.rotateImage(degree,image);            }            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();            image.compress(Bitmap.CompressFormat.JPEG,80,byteArrayOutputStream);            imageData = byteArrayOutputStream.toByteArray();            ((ImageView)findViewById(R.id.imageViewHead)).setImageBitmap(image);        }    }    @Override    public void finish() {        if(null != progressDialog){            progressDialog.dismiss();        }        super.finish();    }    private void updataGallery(String fileName) {        MediaScannerConnection.scanFile(this, new String[]{fileName}, null,                new MediaScannerConnection.OnScanCompletedListener() {                    @Override                    public void onScanCompleted(String path, Uri uri) {                    }                });    }    /**     * 请求对象监听  , 对服务器返回来的数据进行解析  JSON格式     */    private RequestListener requestListener = new RequestListener() {        @Override        public void onEvent(int i, Bundle bundle) {        }        @Override        public void onBufferReceived(byte[] bytes) {            if(null != progressDialog){                progressDialog.dismiss();            }            try {                String result = new String(bytes,"utf-8");                Log.i(TAG,result);                JSONObject object = new JSONObject(result);                String type = object.optString("sst");//获取业务类型                if("reg".equals(type)){//注册                    register(object);                }else if("verify".equals(type)){//校验                    verify(object);                }else if("detect".equals(type)){                    detect(object);                }else if("aligm".equals(type)){                  //align(object);                }            } catch (UnsupportedEncodingException e) {                e.printStackTrace();            } catch (JSONException e) {                e.printStackTrace();            }        }        @Override        public void onCompleted(SpeechError speechError) {//完成后            if(null != progressDialog){                progressDialog.dismiss();            }            if(speechError != null ){                switch (speechError.getErrorCode()){                    case ErrorCode.MSP_ERROR_ALREADY_EXIST:                        showToast("密钥已被注册,请更换后再试...");                        break;                    default:showToast(speechError.getPlainDescription(true));                        break;                }            }        }    };    //检测    private void detect(JSONObject object) throws JSONException{        int ret = object.getInt("ret");        if(ret != 0){            showToast("检测失败");        }else if("success".equals(object.get("rst"))){            JSONArray jsonArray = object.getJSONArray("face");            Paint paint = new Paint();            paint.setColor(Color.RED);            paint.setStrokeWidth(Math.max(image.getWidth(), image.getHeight()) / 100f);            Bitmap bitmap = Bitmap.createBitmap(image.getWidth(),image.getHeight(), Bitmap.Config.ARGB_8888);            Canvas canvas = new Canvas(bitmap);            canvas.drawBitmap(image,new Matrix(),null);            for(int i = 0;i<jsonArray.length();i++){                float x1 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("left");                float y1 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("top");                float x2 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("right");                float y2 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("bottom");                paint.setStyle(Paint.Style.STROKE);                canvas.drawRect(new Rect((int)x1,(int)x2,(int)x2,(int)y2),paint);            }            image = bitmap;            ((ImageView)findViewById(R.id.imageViewHead)).setImageBitmap(image);        }else {            showToast("检测失败");        }    }    /**     * 校验      * @param object     */    private void verify(JSONObject object) throws JSONException{        int ret = object.getInt("ret");        Log.i(TAG,"ret校验"+ret);        if(ret != 0){            showToast("校验失败..."+ret);        }else if("success".equals(object.get("rst"))){            if(object.getBoolean("verf")){                showToast("验证通过");                editTextUserPassword.setText(null);                startActivity(new Intent(MainActivity.this,JumpActivity.class));            }else if(!object.getBoolean("verg")){                showToast("验证不通过");            }else showToast("验证失败");        }    }    /**     * 如果收回的数据类型是注册 进行一下处理      * @param object     */    private void register(JSONObject object) throws JSONException{        int ret = object.getInt("ret");//解析ret返回值  0代表成功 -1失败  或者其他的错误异常代码        if(ret != 0){            showToast("注册失败");            return;        }else if("success".equals(object.get("rst"))){            showToast("注册成功");            editTextUserPassword.setText(null);        }else showToast("注册失败,错误");    }    //土司对话框    private void showToast(final String s){        toast.setText(s);        toast.show();    }}

Ok 就这个简单。

效果:


源码  http://download.csdn.net/detail/csdnhejingzhou/9470349

0 0
原创粉丝点击