這篇文章將為大家詳細(xì)講解有關(guān)在Android 開(kāi)發(fā)中使用camera怎么實(shí)現(xiàn)一個(gè)人臉識(shí)別功能,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),上城網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:上城等地區(qū)。上城做網(wǎng)站價(jià)格咨詢:18980820575
Android camera實(shí)時(shí)預(yù)覽 實(shí)時(shí)處理,面部認(rèn)證。
預(yù)覽操作是網(wǎng)友共享的代碼,我在繼承SurfaceView 的CameraSurfaceView 中加入了幀監(jiān)聽(tīng)事件,每次預(yù)覽監(jiān)聽(tīng)前五個(gè)數(shù)據(jù)幀,在處理做一個(gè)面部識(shí)別。
先看目錄關(guān)系
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; //傳輸五個(gè)bitmap數(shù)組 Bitmap [] bitmaps = new Bitmap[5]; int number = 0;//作為計(jì)數(shù)器用 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; } /** * 收集五張圖片 監(jiān)聽(tīng)器 */ public static interface OnFaceCollectListener { /** * 收集五張face * @param bitmaps 返回的五張臉的數(shù)組 */ void OnFaceCollected(Bitmap[] bitmaps); /** * face重新繪制 * @param isStart 是否重新收集 */ void OnFaceCollectStart(boolean isStart); } /** * 設(shè)置面部的監(jiān)聽(tīng)器 * @param onFaceCollectListener */ public void setOnFaceCollectListener(OnFaceCollectListener onFaceCollectListener){ if(onFaceCollectListener!=null){ this.onFaceCollectListener = onFaceCollectListener; } } /*** * 想在這里做一個(gè)監(jiān)聽(tīng)處理 收五偵 傳輸出去 * @param bytes * @param camera */ @Override public void onPreviewFrame(byte[] bytes, Camera camera) { if(number<FACENUM){ //收集 //判斷監(jiān)聽(tīng)器 開(kāi)始 if(onFaceCollectListener!=null){ onFaceCollectListener.OnFaceCollectStart(true); //有byte數(shù)組轉(zhuǎn)為bitmap bitmaps[number] = byte2bitmap(bytes,camera); Log.d("ceshiTian","********收集了"+number+"個(gè)************"); number = number+1; if(number==5){ Log.d("ceshiTian","********收集夠5個(gè)************"); //提交 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(); // 獲取預(yù)覽大小 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; } /** * 打開(kāi)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(); } /** * 開(kāi)啟預(yù)覽 * * @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);//設(shè)置拍照后存儲(chǔ)的圖片格式 //對(duì)支持的圖片的大小的一個(gè)收集 CamParaUtil.getInstance().printSupportPictureSize(mParams); CamParaUtil.getInstance().printSupportPreviewSize(mParams); //設(shè)置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); //參數(shù)設(shè)置完畢 try { mCamera.setPreviewDisplay(holder); mCamera.setPreviewCallback(previewCallback); mCamera.startPreview();//開(kāi)啟預(yù)覽 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } isPreviewing = true; mPreviwRate = previewRate; mParams = mCamera.getParameters(); //重新get一次 Log.i(TAG, "最終設(shè)置:PreviewSize--With = " + mParams.getPreviewSize().width + "Height = " + mParams.getPreviewSize().height); Log.i(TAG, "最終設(shè)置:PictureSize--With = " + mParams.getPictureSize().width + "Height = " + mParams.getPictureSize().height); } } /** * 停止預(yù)覽,釋放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", "程序運(yùn)行到這里了111"); mCamera.takePicture(mShutterCallback, null, mJpegPictureCallback); } } /*為了實(shí)現(xiàn)拍照的快門聲音及拍照保存照片需要下面三個(gè)回調(diào)變量*/ Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() //快門按下的回調(diào),在這里我們可以設(shè)置類似播放“咔嚓”聲之類的操作。默認(rèn)的就是咔嚓。 { public void onShutter() { // TODO Auto-generated method stub Log.i(TAG, "myShutterCallback:onShutter..."); } }; /* Camera.PictureCallback mRawCallback = new Camera.PictureCallback() // 拍攝的未壓縮原數(shù)據(jù)的回調(diào),可以為null { public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub Log.i(TAG, "myRawCallback:onPictureTaken..."); } };*/ Camera.PictureCallback mJpegPictureCallback = new Camera.PictureCallback() //對(duì)jpeg圖像數(shù)據(jù)的回調(diào),最重要的一個(gè)回調(diào) { public void onPictureTaken(byte[] data, Camera camera) { Log.d("FileUtils", "程序運(yùn)行到這里了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是字節(jié)數(shù)據(jù),將其解析成位圖 mCamera.stopPreview(); isPreviewing = false; Log.d("FileUtils", "程序運(yùn)行到這里了333"); } //保存圖片到sdcard if (null != b) { Log.d("FileUtils", "程序運(yùn)行到這里了444"); //設(shè)置FOCUS_MODE_CONTINUOUS_VIDEO)之后,myParam.set("rotation", 90)失效。 //圖片竟然不能旋轉(zhuǎn)了,故這里要旋轉(zhuǎn)下 Log.d("FileUtils", "程序運(yùn)行到這里了"); 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); } /** * 回調(diào)方法 * activity中的視圖和 interface中的代碼實(shí)現(xiàn)綁定 */ @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("檢測(cè)時(shí)間:" + 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); //默認(rèn)全屏的比例預(yù)覽 surfaceView.setLayoutParams(params); //手動(dòng)設(shè)置拍照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 返回的五張臉的數(shù)組 */ @Override public void OnFaceCollected(Bitmap[] bitmaps) { } /** * 自建 * @param isStart 是否重新收集 */ @Override public void OnFaceCollectStart(boolean isStart) { if(isStart){ Log.d("CameraActivity","開(kāi)始收集"); } } 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); // 默認(rèn)一個(gè)暫存的路徑 /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; } } } }
關(guān)于在Android 開(kāi)發(fā)中使用camera怎么實(shí)現(xiàn)一個(gè)人臉識(shí)別功能就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
新聞標(biāo)題:在Android開(kāi)發(fā)中使用camera怎么實(shí)現(xiàn)一個(gè)人臉識(shí)別功能
當(dāng)前網(wǎng)址:http://aaarwkj.com/article14/gihgge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、虛擬主機(jī)、服務(wù)器托管、網(wǎng)站設(shè)計(jì)、微信公眾號(hào)、營(yíng)銷型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)