android基于opencv的车牌识别,高识别率
android基于opencv的车牌识别(LPR),高识别率
LPR是一个开源的车牌识别的框架,源码在此,大家可以去github下载
LPR源码
https://github.com/zeusees/HyperLPR.git
下面我们一步步来如何移植LPR到Android
开发IDE是android stduio
我们先来移植一下Opencv到android上。
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
官网下载sdk
https://opencv.org/
OPENCV
首先新建一个项目
这些根据你自己填
创建新工程完成
移植opencv,打开opencv的sdk的java目录·
把它复制到工程上
然后导入
选择刚刚的java目录
导入
点完成
然后编译的时候会出现报错我们需要改一下Androidmanifest.xml文件
把下面的那一行注释掉
还有就是,在open
apply plugin: 'com.android.library'android { compileSdkVersion 29 buildToolsVersion "29.0.2" defaultConfig { minSdkVersion 8 targetSdkVersion 29 } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } }}
然后添加依赖
implementation project(path: ':openCVLibrary343')
然后再MainActivity.java添加以下代码
@Override protected void onResume() { super.onResume(); if (!OpenCVLoader.initDebug()) { Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization"); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, getApplicationContext(), mLoaderCallback); } else { Log.d(TAG, "OpenCV library found inside package. Using it!"); mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } }
最后添加so库
打开opencv复制opencv_sdk\OpenCV-android-sdk\sdk\native\libs里面的v7a库,当然也可以全部复制过去
复制过去后的样子
添加这段代码到app的
build.gradle上
然后android 的opencv环境搭建好了
然后要用到NDK,
NDK:(Native Development Kit),原生开发工具包是一组可以让您在Android应用中利用C和c++代码的工具,可用以从您自己的源代码构建,或者利用现有的预构建库.
我们用到的NDK版本是r14的,注意(版本太高不行,目前用r14稳定)
这里是下载链接
ndk_r14b (Dec 2016)
Windows 32-bit : https://dl.google.com/android/repository/android-ndk-r14b-windows-x86.zip
Windows 64-bit :
https://dl.google.com/android/repository/android-ndk-r14b-windows-x86_64.zip
把这里改成自己的目录
添加Lpr模型
添加jni
把这几个文件复制过去
javaWarpper.cpp里面记得替换成自己的包名
添加CMakeLists.txt文件,自己复制过去
这里修改成自己的本地路径
修改
最后的样子
apply plugin: 'com.android.application'android { compileSdkVersion 29 buildToolsVersion "29.0.2" defaultConfig { applicationId "com.plate.lpr" minSdkVersion 15 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } sourceSets { main { jniLibs.srcDirs = ['src/main/jniLibs'] jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } } externalNativeBuild { cmake { path "CMakeLists.txt" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility = '1.8' targetCompatibility = '1.8' }}dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation project(path: ':openCVLibrary343')}
布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" > <ImageView android:id="@+id/img" android:layout_width="350dp" android:layout_height="200dp" android:layout_gravity="center" android:layout_marginTop="100dp" android:layout_marginBottom="100dp"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="调入图片" android:layout_gravity="center" android:id="@+id/in_img"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="识别" android:layout_gravity="center" android:id="@+id/reg"/></LinearLayout>
剩下的java部分
import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import android.Manifest;import android.annotation.SuppressLint;import android.content.ContentResolver;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.AsyncTask;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;import org.opencv.android.BaseLoaderCallback;import org.opencv.android.LoaderCallbackInterface;import org.opencv.android.OpenCVLoader;import org.opencv.android.Utils;import org.opencv.core.Mat;import java.io.FileNotFoundException;public class MainActivity extends AppCompatActivity { private ImageView imageView; private Button in_b,re_b; private Bitmap bitmap1; public long handle; private String re_str; private final String TAG = getClass().getSimpleName(); private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @SuppressLint("StaticFieldLeak") @Override public void onManagerConnected(int status) { super.onManagerConnected(status); if (status == LoaderCallbackInterface.SUCCESS) { handle = DeepAssetUtil.initRecognizer(MainActivity.this); Log.d(TAG, "OpenCV 加载成功"); } else { Log.d(TAG, "OpenCV 加载失败"); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestDangerousPermissions(); imageView=findViewById(R.id.img); in_b=findViewById(R.id.in_img); re_b=findViewById(R.id.reg); in_b.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //intent可以应用于广播和发起意图,其中属性有:ComponentName,action,data等 Intent intent=new Intent(); intent.setType("image/*"); //action表示intent的类型,可以是查看、删除、发布或其他情况;我们选择ACTION_GET_CONTENT,系统可以根据Type类型来调用系统程序选择Type //类型的内容给你选择 intent.setAction(Intent.ACTION_GET_CONTENT); //如果第二个参数大于或等于0,那么当用户操作完成后会返回到本程序的onActivityResult方法 startActivityForResult(intent, 1); } }); re_b.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Mat m=new Mat(); Utils.bitmapToMat(bitmap1,m); re_str=PlateRecognition.SimpleRecognization(m.getNativeObjAddr(), handle); } }); } @Override protected void onResume() { super.onResume(); if (!OpenCVLoader.initDebug()) { Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization"); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, getApplicationContext(), mLoaderCallback); } else { Log.d(TAG, "OpenCV library found inside package. Using it!"); mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } } public void requestDangerousPermissions() { String[] strings = new String[]{ //Manifest.permission.CAMERA, //Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; ActivityCompat.requestPermissions(this, strings, 100); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //用户操作完成,结果码返回是-1,即RESULT_OK if(resultCode==RESULT_OK){ //获取选中文件的定位符 Uri uri = data.getData(); Log.e("uri", uri.toString()); //使用content的接口 ContentResolver cr = this.getContentResolver(); try { //获取图片 bitmap1 = BitmapFactory.decodeStream(cr.openInputStream(uri)); imageView.setImageBitmap(bitmap1); } catch (FileNotFoundException e) { Log.e("Exception", e.getMessage(),e); } }else{ //操作错误或没有选择图片 Log.i("MainActivtiy", "operation error"); } super.onActivityResult(requestCode, resultCode, data); }}
添加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
完成后
会发现多了一个.so文件
还有一部分代码就不贴上来的,比较长。大家去下载吧!
关注公众号回复003即可下载
更多相关文章
- 在Ubuntu中和Android中添加开机自启动的守护进程
- Android(安卓)View框架总结(一)
- 如何设置Android的AVD模拟器可以输入中文
- Android(安卓)AndroidMainifest.xml 中 Android:sharedUserId
- Android(安卓)Secret Code
- Android(安卓)获取进程名称(可以区分内部进程)
- android源码下载, 看了几篇博客,综合下成功了。
- Android中读如何取另一个apk中的资源
- Android的Message Queue