首页 > 系统 > Android > 正文

Android camera实时预览 实时处理,人脸识别示例

2019-12-12 03:57:27
字体:
来源:转载
供稿:网友

Android camera实时预览 实时处理,面部认证。

预览操作是网友共享的代码,我在继承SurfaceView 的CameraSurfaceView 中加入了帧监听事件,每次预览监听前五个数据帧,在处理做一个面部识别。

先看目录关系

  • 自定义控件CameraSurfaceView.java
  • 自定义接口方法CameraInterface.java
  • CameraActivity预览界面。

CameraSurfaceView.Java

package com.centaur.camera.preview;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.ImageFormat;import android.graphics.Matrix;import android.graphics.PixelFormat;import android.graphics.Rect;import android.graphics.YuvImage;import android.hardware.Camera;import android.util.AttributeSet;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import com.centaur.camera.camera.CameraInterface;import java.io.ByteArrayOutputStream;/** * Created by Tianchaoxiong on 2017/1/16. */public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback{  private static final int FACENUM = 5;  private static final String TAG = "yanzi";  CameraInterface mCameraInterface;  Context mContext;  SurfaceHolder mSurfaceHolder;  private boolean isFinish;  //传输五个bitmap数组  Bitmap [] bitmaps = new Bitmap[5];  int number = 0;//作为计数器用  OnFaceCollectListener onFaceCollectListener = null;  public CameraSurfaceView(Context context, AttributeSet attrs) {    super(context, attrs);    mContext = context;    mSurfaceHolder = getHolder();    mSurfaceHolder.setFormat(PixelFormat.TRANSPARENT);//translucent半透明 transparent透明    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    mSurfaceHolder.addCallback(this);  }  @Override  public void surfaceCreated(SurfaceHolder surfaceHolder) {    Log.i(TAG, "surfaceCreated...");  }  @Override  public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {    Log.i(TAG, "surfaceChanged...");  }  @Override  public void surfaceDestroyed(SurfaceHolder surfaceHolder) {    Log.i(TAG, "surfaceDestroyed...");    CameraInterface.getInstance().doStopCamera();  }  public SurfaceHolder getSurfaceHolder(){    return mSurfaceHolder;  }  /**   * 收集五张图片 监听器   */  public static interface OnFaceCollectListener {    /**     * 收集五张face     * @param bitmaps 返回的五张脸的数组     */    void OnFaceCollected(Bitmap[] bitmaps);    /**     * face重新绘制     * @param isStart 是否重新收集     */    void OnFaceCollectStart(boolean isStart);  }  /**   * 设置面部的监听器   * @param onFaceCollectListener   */  public void setOnFaceCollectListener(OnFaceCollectListener onFaceCollectListener){    if(onFaceCollectListener!=null){      this.onFaceCollectListener = onFaceCollectListener;    }  }  /***   * 想在这里做一个监听处理 收五侦 传输出去   * @param bytes   * @param camera   */  @Override  public void onPreviewFrame(byte[] bytes, Camera camera) {    if(number<FACENUM){      //收集      //判断监听器 开始      if(onFaceCollectListener!=null){        onFaceCollectListener.OnFaceCollectStart(true);        //有byte数组转为bitmap        bitmaps[number] = byte2bitmap(bytes,camera);        Log.d("ceshiTian","********收集了"+number+"个************");        number = number+1;        if(number==5){          Log.d("ceshiTian","********收集够5个************");          //提交          onFaceCollectListener.OnFaceCollected(bitmaps);        }      }    }else {      //不做操作      onFaceCollectListener.OnFaceCollectStart(false);      onFaceCollectListener.OnFaceCollected(null);    }  }  private Bitmap byte2bitmap(byte[] bytes, Camera camera) {    Bitmap bitmap = null;    Camera.Size size = camera.getParameters().getPreviewSize(); // 获取预览大小    final int w = size.width; // 宽度    final int h = size.height;    final YuvImage image = new YuvImage(bytes, ImageFormat.NV21, w, h,        null);    ByteArrayOutputStream os = new ByteArrayOutputStream(bytes.length);    if (!image.compressToJpeg(new Rect(0, 0, w, h), 100, os)) {      return null;    }    byte[] tmp = os.toByteArray();    bitmap = BitmapFactory.decodeByteArray(tmp, 0, tmp.length);    Matrix matrix = new Matrix();    matrix.setRotate(-90);    bitmap = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);    return bitmap;  }}

CameraInterface.java

package com.centaur.camera.camera;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.ImageFormat;import android.graphics.Matrix;import android.graphics.PixelFormat;import android.graphics.Rect;import android.graphics.YuvImage;import android.hardware.Camera;import android.util.Log;import android.view.SurfaceHolder;import com.centaur.camera.util.CamParaUtil;import com.centaur.camera.util.ImageUtil;import com.centaur.util.FileUtils;import java.io.IOException;import java.util.List;/** * Created by Tianchaoxiong on 2017/1/16. */public class CameraInterface {  private static final String TAG = "Tianchaoxiong";  private Camera mCamera;  private Camera.Parameters mParams;  private boolean isPreviewing = false;  private float mPreviwRate = -1f;  private static CameraInterface mCameraInterface;  public interface CamOpenOverCallback {    public void cameraHasOpened();  }  private CameraInterface() {  }  public static synchronized CameraInterface getInstance() {    if (mCameraInterface == null) {      mCameraInterface = new CameraInterface();    }    return mCameraInterface;  }  /**   * 打开Camera   *   * @param callback   */  public void doOpenCamera(CamOpenOverCallback callback) {    Log.i(TAG, "Camera open....");    mCamera = Camera.open(1);    Log.i(TAG, "Camera open over....");    callback.cameraHasOpened();  }  /**   * 开启预览   *   * @param holder   * @param previewRate   */  public void doStartPreview(SurfaceHolder holder, float previewRate, Camera.PreviewCallback previewCallback) {    Log.i(TAG, "doStartPreview...");    if (isPreviewing) {      mCamera.stopPreview();      return;    }    if (mCamera != null) {      mParams = mCamera.getParameters();      mParams.setPictureFormat(PixelFormat.JPEG);//设置拍照后存储的图片格式      //对支持的图片的大小的一个收集      CamParaUtil.getInstance().printSupportPictureSize(mParams);      CamParaUtil.getInstance().printSupportPreviewSize(mParams);      //设置PreviewSize和PictureSize      Camera.Size pictureSize = CamParaUtil.getInstance().getPropPictureSize(          mParams.getSupportedPictureSizes(), previewRate, 800);      mParams.setPictureSize(pictureSize.width, pictureSize.height);      Camera.Size previewSize = CamParaUtil.getInstance().getPropPreviewSize(          mParams.getSupportedPreviewSizes(), previewRate, 800);      mParams.setPreviewSize(previewSize.width, previewSize.height);      mCamera.setDisplayOrientation(90);      CamParaUtil.getInstance().printSupportFocusMode(mParams);      List<String> focusModes = mParams.getSupportedFocusModes();      if (focusModes.contains("continuous-video")) {        mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);      }      mCamera.setParameters(mParams);  //参数设置完毕      try {        mCamera.setPreviewDisplay(holder);        mCamera.setPreviewCallback(previewCallback);        mCamera.startPreview();//开启预览      } catch (IOException e) {        // TODO Auto-generated catch block        e.printStackTrace();      }      isPreviewing = true;      mPreviwRate = previewRate;      mParams = mCamera.getParameters(); //重新get一次      Log.i(TAG, "最终设置:PreviewSize--With = " + mParams.getPreviewSize().width          + "Height = " + mParams.getPreviewSize().height);      Log.i(TAG, "最终设置:PictureSize--With = " + mParams.getPictureSize().width          + "Height = " + mParams.getPictureSize().height);    }  }  /**   * 停止预览,释放Camera   */  public void doStopCamera() {    if (null != mCamera) {      mCamera.setPreviewCallback(null);      mCamera.stopPreview();      isPreviewing = false;      mPreviwRate = -1f;      mCamera.release();      mCamera = null;    }  }  /**   * 拍照   */  public void doTakePicture() {    if (isPreviewing && (mCamera != null)) {      Log.d("FileUtils", "程序运行到这里了111");      mCamera.takePicture(mShutterCallback, null, mJpegPictureCallback);    }  }  /*为了实现拍照的快门声音及拍照保存照片需要下面三个回调变量*/  Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback()      //快门按下的回调,在这里我们可以设置类似播放“咔嚓”声之类的操作。默认的就是咔嚓。  {    public void onShutter() {      // TODO Auto-generated method stub      Log.i(TAG, "myShutterCallback:onShutter...");    }  };  /*  Camera.PictureCallback mRawCallback = new Camera.PictureCallback()        // 拍摄的未压缩原数据的回调,可以为null    {      public void onPictureTaken(byte[] data, Camera camera) {        // TODO Auto-generated method stub        Log.i(TAG, "myRawCallback:onPictureTaken...");      }    };*/  Camera.PictureCallback mJpegPictureCallback = new Camera.PictureCallback()      //对jpeg图像数据的回调,最重要的一个回调  {    public void onPictureTaken(byte[] data, Camera camera) {      Log.d("FileUtils", "程序运行到这里了222");      // TODO Auto-generated method stub      Log.i(TAG, "myJpegCallback:onPictureTaken...");      Bitmap b = null;      if (null != data) {        b = BitmapFactory.decodeByteArray(data, 0, data.length);//data是字节数据,将其解析成位图        mCamera.stopPreview();        isPreviewing = false;        Log.d("FileUtils", "程序运行到这里了333");      }      //保存图片到sdcard      if (null != b) {        Log.d("FileUtils", "程序运行到这里了444");        //设置FOCUS_MODE_CONTINUOUS_VIDEO)之后,myParam.set("rotation", 90)失效。        //图片竟然不能旋转了,故这里要旋转下        Log.d("FileUtils", "程序运行到这里了");        Bitmap rotaBitmap = ImageUtil.getRotateBitmap(b, -90.0f);        FileUtils.savePaiZhaoBitmap(rotaBitmap);      }    }  };}

CameraActivity

package com.centaur.camera.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.Point;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.SurfaceHolder;import android.view.View;import android.view.ViewGroup;import android.widget.ImageButton;import android.widget.TextView;import com.centaur.camera.camera.CameraInterface;import com.centaur.camera.preview.CameraSurfaceView;import com.centaur.camera.util.DisplayUtil;import com.centaur.testutil.R;import com.centaur.testutil.ShowPic;import com.centaur.util.DetecteSDK;import com.centaur.util.DetecteSeeta;public class CameraActivity extends AppCompatActivity implements CameraSurfaceView.OnFaceCollectListener, CameraInterface.CamOpenOverCallback{  private static final String TAG = "CameraActivity";  private float recLen = 0;  long te;  float previewRate = -1f;  DetecteSDK detecteSDK;  DetecteSeeta detecteSeeta;  Bitmap bmp;  Bitmap bitmapfianl;  private ImageButton shutterBtn;  private TextView textView;  private CameraSurfaceView surfaceView = null;  @Override  protected void onCreate(Bundle savedInstanceState){    super.onCreate(savedInstanceState);    Thread openThread = new Thread(){      @Override      public void run() {        CameraInterface.getInstance().doOpenCamera(CameraActivity.this);      }    };    openThread.start();    te = System.currentTimeMillis();    setContentView(R.layout.activity_camera);    initView();    initViewParams();    surfaceView.setOnFaceCollectListener(this);    shutterBtn.setOnClickListener(new BtnListeners());    TimeHandler.postDelayed(TimeRunnable, 500);  }  /**   * 回调方法   * activity中的视图和 interface中的代码实现绑定   */  @Override  public void cameraHasOpened() {    SurfaceHolder holder = surfaceView.getSurfaceHolder();    CameraInterface.getInstance().doStartPreview(holder, previewRate,surfaceView );  }  @Override  protected void onDestroy() {    // TODO Auto-generated method stub    super.onDestroy();    CameraInterface.getInstance().doStopCamera();    Log.d("RunTime", "onDestroy:time:"+te);    TimeHandler.removeCallbacks(TimeRunnable);  }  @Override  protected void onPause() {    // TODO Auto-generated method stub    super.onPause();    CameraInterface.getInstance().doStopCamera();    te = System.currentTimeMillis()-te;    Log.d("RunTime", "onPause:time:"+te);    TimeHandler.removeCallbacks(TimeRunnable);  }  Handler TimeHandler = new Handler();  Runnable TimeRunnable = new Runnable() {    @Override    public void run() {      recLen+=500;      textView.setText("检测时间:" + recLen/1000+"秒");      TimeHandler.postDelayed(this, 500);    }  };  private void initView(){    surfaceView = (CameraSurfaceView)findViewById(R.id.camera_surfaceview);    shutterBtn = (ImageButton)findViewById(R.id.btn_shutter);    textView = (TextView) findViewById(R.id.time);  }  private void initViewParams(){    ViewGroup.LayoutParams params = surfaceView.getLayoutParams();    Point p = DisplayUtil.getScreenMetrics(this);    params.width = p.x;    params.height = p.y;    previewRate = DisplayUtil.getScreenRate(this); //默认全屏的比例预览    surfaceView.setLayoutParams(params);    //手动设置拍照ImageButton的大小为120dip×120dip,原图片大小是64×64    ViewGroup.LayoutParams p2 = shutterBtn.getLayoutParams();    p2.width = DisplayUtil.dip2px(this, 80);    p2.height = DisplayUtil.dip2px(this, 80);    shutterBtn.setLayoutParams(p2);  }  /**   * 自建   * @param bitmaps 返回的五张脸的数组   */  @Override  public void OnFaceCollected(Bitmap[] bitmaps) {  }  /**   * 自建   * @param isStart 是否重新收集   */  @Override  public void OnFaceCollectStart(boolean isStart) {    if(isStart){      Log.d("CameraActivity","开始收集");    }  }  private class BtnListeners implements View.OnClickListener {    @Override    public void onClick(View v) {      // TODO Auto-generated method stub      switch(v.getId()){        case R.id.btn_shutter:          CameraInterface.getInstance().doTakePicture();          Intent intent =new Intent(CameraActivity.this, ShowPic.class);          // 默认一个暂存的路径 /FaceDetection/useso/Pictures/Tmp/tmp.png          String FolderPath = "/FaceDetection/useso/Pictures/Tmp/tmp.png";          String path = Environment.getExternalStorageDirectory()+FolderPath;          intent.putExtra("picpath",path);          startActivity(intent);          finish();          break;        default:break;      }    }  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表