实例介绍
【实例简介】
在安卓系统内实现车牌号自动识别
【实例截图】
【核心代码】
package com.aiseminar.platerecognizer.ui; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Rect; import android.graphics.YuvImage; import android.hardware.Camera; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.DisplayMetrics; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.aiseminar.EasyPR.PlateRecognizer; import com.aiseminar.platerecognizer.R; import com.aiseminar.platerecognizer.base.BaseActivity; import com.aiseminar.util.BitmapUtil; import com.aiseminar.util.DateUtil; import com.aiseminar.util.FileUtil; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; public class CameraActivity extends BaseActivity implements SurfaceHolder.Callback { @Bind(R.id.svCamera) SurfaceView mSvCamera; @Bind(R.id.ivPlateRect) ImageView mIvPlateRect; @Bind(R.id.ivCapturePhoto) ImageView mIvCapturePhoto; @Bind(R.id.tvPlateResult) TextView mTvPlateResult; private static final String TAG = CameraActivity.class.getSimpleName(); private int cameraPosition = 0; // 0表示后置,1表示前置 private SurfaceHolder mSvHolder; private Camera mCamera; private Camera.CameraInfo mCameraInfo; private MediaPlayer mShootMP; private PlateRecognizer mPlateRecognizer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); ButterKnife.bind(this); mPlateRecognizer = new PlateRecognizer(this); initData(); } @Override public void onStart() { super.onStart(); if (this.checkCameraHardware(this) && (mCamera == null)) { // 打开camera mCamera = getCamera(); // 设置camera方向 mCameraInfo = getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK); if (null != mCameraInfo) { adjustCameraOrientation(); } if (mSvHolder != null) { setStartPreview(mCamera, mSvHolder); } } } @Override public void onPause() { super.onPause(); /** * 记得释放camera,方便其他应用调用 */ releaseCamera(); } @Override public void onDestroy() { super.onDestroy(); } /** * 初始化相关data */ private void initData() { // 获得句柄 mSvHolder = mSvCamera.getHolder(); // 获得句柄 // 添加回调 mSvHolder.addCallback(this); } private Camera getCamera() { Camera camera = null; try { camera = Camera.open(); } catch (Exception e) { // Camera is not available (in use or does not exist) camera = null; Log.e(TAG, "Camera is not available (in use or does not exist)"); } return camera; } private Camera.CameraInfo getCameraInfo(int facing) { int numberOfCameras = Camera.getNumberOfCameras(); Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); for (int i = 0; i < numberOfCameras; i ) { Camera.getCameraInfo(i, cameraInfo); if (cameraInfo.facing == facing) { return cameraInfo; } } return null; } private void adjustCameraOrientation() { // 调整摄像头方向 if (null == mCameraInfo || null == mCamera) { return; } int orientation = this.getWindowManager().getDefaultDisplay().getOrientation(); int degrees = 0; switch (orientation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (mCameraInfo.orientation degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (mCameraInfo.orientation - degrees 360) % 360; } mCamera.setDisplayOrientation(result); } /** * 释放mCamera */ private void releaseCamera() { if (mCamera != null) { mCamera.setPreviewCallback(null); mCamera.stopPreview();// 停掉原来摄像头的预览 mCamera.release(); mCamera = null; } } @OnClick({R.id.ivCapturePhoto}) public void onClick(View view) { switch (view.getId()) { case 999: // R.id.id_switch_camera_btn: // 切换前后摄像头 int cameraCount = 0; Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); cameraCount = Camera.getNumberOfCameras();// 得到摄像头的个数 for (int i = 0; i < cameraCount; i ) { Camera.getCameraInfo(i, cameraInfo);// 得到每一个摄像头的信息 if (cameraPosition == 1) { // 现在是后置,变更为前置 if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { /** * 记得释放camera,方便其他应用调用 */ releaseCamera(); // 打开当前选中的摄像头 mCamera = Camera.open(i); // 通过surfaceview显示取景画面 setStartPreview(mCamera,mSvHolder); cameraPosition = 0; break; } } else { // 现在是前置, 变更为后置 if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { /** * 记得释放camera,方便其他应用调用 */ releaseCamera(); mCamera = Camera.open(i); setStartPreview(mCamera,mSvHolder); cameraPosition = 1; break; } } } break; case R.id.ivCapturePhoto: // 拍照,设置相关参数 // Camera.Parameters params = mCamera.getParameters(); // params.setPictureFormat(ImageFormat.JPEG); // DisplayMetrics metric = new DisplayMetrics(); // getWindowManager().getDefaultDisplay().getMetrics(metric); // int width = metric.widthPixels; // 屏幕宽度(像素) // int height = metric.heightPixels; // 屏幕高度(像素) // params.setPreviewSize(width, height); // // 自动对焦 // params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); // mCamera.setParameters(params); try { mCamera.takePicture(shutterCallback, null, jpgPictureCallback); } catch (Exception e) { Log.d(TAG, e.getMessage()); } break; } } @Override public void surfaceCreated(SurfaceHolder holder) { setStartPreview(mCamera, mSvHolder); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. if (mSvHolder.getSurface() == null) { // preview surface does not exist return; } // stop preview before making changes try { mCamera.stopPreview(); } catch (Exception e) { // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings setStartPreview(mCamera, mSvHolder); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 当surfaceview关闭时,关闭预览并释放资源 /** * 记得释放camera,方便其他应用调用 */ releaseCamera(); holder = null; mSvCamera = null; } /** * TakePicture回调 */ Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() { public void onShutter() { shootSound(); mCamera.setOneShotPreviewCallback(previewCallback); } }; Camera.PictureCallback rawPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { camera.startPreview(); } }; Camera.PictureCallback jpgPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { camera.startPreview(); File pictureFile = FileUtil.getOutputMediaFile(FileUtil.FILE_TYPE_IMAGE); if (pictureFile == null) { Log.d(TAG, "Error creating media file, check storage permissions: "); return; } try { FileOutputStream fos = new FileOutputStream(pictureFile); // 照片转方向 Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Bitmap normalBitmap = BitmapUtil.createRotateBitmap(bitmap); // fos.write(data); normalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.close(); // 更新图库 // 把文件插入到系统图库 // try { // MediaStore.Images.Media.insertImage(CameraActivity.this.getContentResolver(), // pictureFile.getAbsolutePath(), pictureFile.getName(), "Photo taked by RoadParking."); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } // 最后通知图库更新 CameraActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" pictureFile.getAbsolutePath()))); Toast.makeText(CameraActivity.this, "图像已保存。", Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { Log.d(TAG, "File not found: " e.getMessage()); } catch (IOException e) { Log.d(TAG, "Error accessing file: " e.getMessage()); } } }; /** Check if this device has a camera */ private boolean checkCameraHardware(Context context) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { // this device has a camera return true; } else { // no camera on this device return false; } } /** * activity返回式返回拍照图片路径 * @param mediaFile */ private void returnResult(File mediaFile) { // Intent intent = new Intent(); // intent.setData(Uri.fromFile(mediaFile)); // this.setResult(RESULT_OK, intent); this.finish(); } /** * 设置camera显示取景画面,并预览 * @param camera */ private void setStartPreview(Camera camera,SurfaceHolder holder){ try { camera.setPreviewDisplay(holder); camera.startPreview(); } catch (IOException e) { Log.d(TAG, "Error starting camera preview: " e.getMessage()); } } /** * 播放系统拍照声音 */ private void shootSound() { AudioManager meng = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); int volume = meng.getStreamVolume( AudioManager.STREAM_NOTIFICATION); if (volume != 0) { if (mShootMP == null) mShootMP = MediaPlayer.create(this, Uri.parse("file:///system/media/audio/ui/camera_click.ogg")); if (mShootMP != null) mShootMP.start(); } } /** * 获取Preview界面的截图,并存储 */ Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { // 获取Preview图片转为bitmap并旋转 Camera.Size size = mCamera.getParameters().getPreviewSize(); //获取预览大小 final int w = size.width; //宽度 final int h = size.height; final YuvImage image = new YuvImage(data, ImageFormat.NV21, w, h, null); // 转Bitmap ByteArrayOutputStream os = new ByteArrayOutputStream(data.length); if(! image.compressToJpeg(new Rect(0, 0, w, h), 100, os)) { return; } byte[] tmp = os.toByteArray(); Bitmap bitmap = BitmapFactory.decodeByteArray(tmp, 0, tmp.length); Bitmap rotatedBitmap = BitmapUtil.createRotateBitmap(bitmap); cropBitmapAndRecognize(rotatedBitmap); } }; public void cropBitmapAndRecognize(Bitmap originalBitmap) { // 裁剪出关注区域 DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 屏幕宽度(像素) int height = metric.heightPixels; // 屏幕高度(像素) Bitmap sizeBitmap = Bitmap.createScaledBitmap(originalBitmap, width, height, true); int rectWidth = (int)(mIvPlateRect.getWidth() * 1.5); int rectHight = (int)(mIvPlateRect.getHeight() * 1.5); int[] location = new int[2]; mIvPlateRect.getLocationOnScreen(location); location[0] -= mIvPlateRect.getWidth() * 0.5 / 2; location[1] -= mIvPlateRect.getHeight() * 0.5 / 2; Bitmap normalBitmap = Bitmap.createBitmap(sizeBitmap, location[0], location[1], rectWidth, rectHight); // 保存图片并进行车牌识别 File pictureFile = FileUtil.getOutputMediaFile(FileUtil.FILE_TYPE_PLATE); if (pictureFile == null) { Log.d(TAG, "Error creating media file, check storage permissions: "); return; } try { mTvPlateResult.setText("正在识别..."); FileOutputStream fos = new FileOutputStream(pictureFile); normalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.close(); // 最后通知图库更新 CameraActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" pictureFile.getAbsolutePath()))); // 进行车牌识别 String plate = mPlateRecognizer.recognize(pictureFile.getAbsolutePath()); if (null != plate && ! plate.equalsIgnoreCase("0")) { mTvPlateResult.setText(plate); } else { mTvPlateResult.setText("请调整角度"); } } catch (FileNotFoundException e) { Log.d(TAG, "File not found: " e.getMessage()); } catch (IOException e) { Log.d(TAG, "Error accessing file: " e.getMessage()); } } }
好例子网口号:伸出你的我的手 — 分享!
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)