android 人脸识别边框_Android camera实时预览 实时处理,人脸识别示例

本文介绍了如何在Android中实现相机实时预览并进行人脸识别。通过自定义CameraSurfaceView监听帧数据,收集五个面部图像,使用面部识别技术。详细代码包括CameraSurfaceView、CameraInterface和CameraActivity的实现,展示了如何启动预览、拍照和处理人脸检测。
摘要由CSDN通过智能技术生成

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

//收集

//判断监听器 开始

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 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;

}

}

}

}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值