【实例简介】

在安卓系统内实现车牌号自动识别

【实例截图】

【核心代码】

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

}

}

}

android 生成车牌号,android 车牌号识别系统app源码相关推荐

  1. 计算机毕业设计android的手机点名签到学生请假考勤系统app(源码+系统+mysql数据库+Lw文档)

    项目介绍 完成基于安卓的点名签到学生请假考勤系统的设计和开发.有效地实现学生考勤信息管理的信息化,减轻管理人员的工作负担,高效率.规范化地管理大量的学生考勤信息,并避免人为操作的错误和不规范行为.运用 ...

  2. 基于Android Studio实现的功能强大的购物商城APP源码,可做Android Studio毕业设计、大作业

    Android 购物商城app 完整代码下载地址:基于Android Studio实现的功能强大的购物商城APP源码 实现的功能: 注册 登录 修改密码 重置密码(邮箱验证,考核结束将移除授权码) 商 ...

  3. 基于YOLOv7的室内场景智能识别系统(源码&教程)

    1.项目背景: 近年来,随着移动互联网与定位技术的发展,基于位置服务越来越多地出现在人们的日常生活中.虽然智能手机都包含很多基于位置服务的应用,但是传统的基于位置服务常常将服务范围划分为室内与室外两种 ...

  4. Opencv基于改进VGG19的表情识别系统(源码&Fer2013&教程)

    1.研究背景 在深度学习中,传统的卷积神经网络对面部表情特征的提取不充分以及计算参数量较大的问题,导致分类准确率偏低.因此,提出了一种基于改进的VGG19网络的人脸表情识别算法.首先,对数据进行增强如 ...

  5. Python基于YOLOv7和CRNN的车牌分割&识别系统(源码&教程)

    1.研究背景 随着科技的进步和社会需求的增长,近年来摄像头逐渐高清化.高帧率化,摄像头作为信息获取设备的载体也不再局限于固定场景.路口.路侧.室内.高位.低位等不同场景下产生了各种对于检测识别的需求, ...

  6. Opencv多语言自然场景文本识别系统(源码&教程)

    1. 研究背景 人类在自然场景中可以快速定位并识别看到的文字信息,但是想要计算机做到和人类一样是比较困难的.开发人员一直想要让机器也能识别图像中的文字信息.当然,对于自然场景来说,图像中的信息复杂甚至 ...

  7. Android安卓人脸识别考勤APP源码与介绍

    国内外人脸识别技术已经成熟,我们探讨将签到(考勤或者门禁)与人脸识别有效地结合成一种新型的签到方式,即人脸识别签到系统,这将极大地加快签到速度并且减少人力成本,缩短签到时间.让签到更加的方便快捷和安全 ...

  8. 计算机毕业设计Android手机汽车租赁系统app(源码+系统+mysql数据库+Lw文档)

    项目介绍 目前,随着经济的发展,人民生活水平的提高,使人们对汽车的需求越来越大,而且随着现代科学的发展,计算机进入了几乎一切领域.各行各业都广泛地使用着计算机,他们的数据信息管理离不开计算机技术的支持 ...

  9. 计算机毕业设计之Android的地铁查询系统app(源码+系统+mysql数据库+Lw文档)

    本软件研究了一个Android平台的地铁查询软件实现方案,从数据库数据保存到地铁数据的提取,再到界面的友好展示,最后到一个成型软件的生成这样一个过程,研究了SQLite数据库在Android平台的应用 ...

  10. 计算机毕业设计Android宠物领养救助系统app(源码+系统+mysql数据库+Lw文档)

    项目介绍 在很多地区,狗和猫都处于散养状态,这部分的动物,也经常会变成流浪动物.猫和狗又都有着较高的繁殖率,使流浪猫狗的种群迅速壮大.流浪猫狗因其可能携带的病毒对社区其他居民,尤其是儿童的健康产生威胁 ...

最新文章

  1. 在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库
  2. vivo 全球商城:商品系统架构设计与实践
  3. 交叉验证python_交叉验证
  4. spring什么版本支持java8_升级spring4.1.6和支持java8
  5. centos6.8安装telnet
  6. Python实现Excel与XML之间的转换
  7. 深度学习的未来在单片机身上?
  8. 20.docker events
  9. Leetcode之合并区间
  10. 封装程序报错Failed to execute script pyi_rth_multiprocessing解决办法
  11. webstorm激活破解方法大全
  12. 微机原理与接口技术考点一文全(待更)
  13. 黑马程序员——递归与枚举
  14. 关于读书,请你丢掉对书本的敬畏感
  15. JAVA-获取无限循环小数的循环节
  16. Redis 使用 scan 命令代替 keys
  17. 拳王虚拟项目公社:新媒体多渠道变现,生财有道?
  18. zTree 异步删除节点操作
  19. Android Pixel手机Notification小图标显示白方块问题
  20. 人脸识别技术综述,出自OPPO研究院

热门文章

  1. 软件项目开发报价指南
  2. 新闻管理系统的设计与实现
  3. OpenGL超级宝典(第7版)之第九章片段处理与帧缓冲
  4. 51单片机课程设计数显简易频率计设计
  5. mysql软件可行性分析报告_网上商城系统可行性分析报告.doc
  6. 锐起无盘服务器缓存多少,锐起无盘缓存分析
  7. 图纸管理软件保证图纸最新版本正确方法
  8. 《CCNA学习指南:数据中心(640-911)》——1.2 一般网络的构成
  9. 电信光猫HG2201T超级管理员模式
  10. oracle grant的用法,oracle grant总结