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

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

说的不清晰 代码在下面 是用android studio写的。
代码地址(地址有问题 下午更新)
不好意思因为没有事先说明 代码是再项目里面的facelock那个module里面。
https://share.weiyun.com/2e3f8b18e390e12b1836d6625e541172(这是微云下载连接)
http://download.csdn.net/detail/u012222078/9749716


程序功能:预览camera,并自动收集几个数据帧保存为bitmap数组方便做面部识别的处理


预览操作是网友共享的代码,我在继承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;
            }
        }

    }
}

Android Camera2人脸检测是一种基于Android平台的人脸识别技术,在相机应用程序中运用的一种高级功能。 相比于以前的Camera API,Camera2 API为Android设备的相机功能提供了更高级的控制和更丰富的特性。其中一个重要的特性就是人脸检测功能。 人脸检测是一种计算机图像处理技术,用于在图像或视频中自动检测人脸并识别其特征。Android Camera2 API通过使用人脸检测器(FaceDetector)类来实现这一功能。 使用Camera2 API进行人脸检测的一般步骤如下: 1. 创建一个CameraCaptureSession,用于图像捕获和展示。 2. 创建一个CaptureRequest.Builder对象,配置相机设备的请求参数。 3. 创建一个SurfaceTexture或SurfaceView,用于相机预览。 4. 使用相机设备创建一个CaptureRequest对象,指定捕获的图像格式和目标Surface。 5. 创建一个设置面部检测的FaceDetector对象,并设置相应的参数。 6. 将FaceDetector应用于捕获的图像,并获得检测到的人脸信息。 7. 根据人脸的位置和特征,在相机预览上绘制相应的标记或框。 人脸检测不仅可以用于提高相片的质量,还可以应用于人脸识别、人脸解锁等领域。利用人脸检测功能,开发者可以开发出更多有趣和有用的相机应用程序。 需要注意的是,Android Camera2 API中的人脸检测功能可能因设备的不同而有所不同,可能会受到硬件和软件的限制。因此,在开发应用程序或使用该功能时,需要仔细考虑设备的兼容性和性能问题。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值