一直对图像处理很感兴趣,上次等车无聊时下载了一个车牌识别软件发现效果挺好的,便更加产生了兴趣,开始在网上搜索资料,在网上事先找打了 taotao1233在VC和Anroid上实现的车牌识别方案,自己体验了感觉还不错,但是可识别的车牌比较少,后来又了解到了一款开源方案EasyPR,尝试之后发现识别度很高,并且博主也对识别流程进行了很详细的博文解说。
考虑到Anroid的便携性,平时又方便拍照,故有了将最新的1.4版本的源码移植到Anroid上使用。
移植成功后的源码链接如下:
http://download.csdn.net/detail/daiyinger/9416320
关于源码的说明如下:
1、安装后打开应用后点击 车牌检测即可测试sd卡目录下的默认包含车牌的图片。
2、如果要编译C,ndk我用的是r10e,当然r9c也没问题,我是在cygwin中进行ndk编译的。
3、基于OpenCV-android-sdk3.0,编译时,可将工程拷到OpenCV-android-sdk的sampls目录下。
4、编译后生成的日志在sd卡的ai目录下,首次安装或者升级时也会将.xml文件拷贝到该目录下。
5、显示区的图像指示缩放和拖拽,但体验还需完善,也欢迎大家下载优化后共享出来。
关于如何搭建ndk环境网上资料太多,主要对主要流程和代码做概要说明。
第一步
拷贝EasyPR的src目录到Anroid的工程下的jni目录。
第二步
编写jni接口的函数和接口。
接口头文件com_daiyinger_carplate_CarPlateDetection.h的定义如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_daiyinger_carplate_CarPlateDetection */
#ifndef _Included_com_daiyinger_carplate_CarPlateDetection
#define _Included_com_daiyinger_carplate_CarPlateDetection
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_carplate_CarPlateDetection
* Method: ImageProc
* Signature: ([III)Ljava/lang/String;
*/
JNIEXPORT jbyteArray JNICALL Java_com_daiyinger_carplate_CarPlateDetection_ImageProc
(JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
第三步
为jni代码编写Anroid.mk。
LOCAL_PATH := $(call my-dir)/src
include $(CLEAR_VARS)
# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include ../../sdk/native/jni/OpenCV.mk
FILE_LIST := $(wildcard $(LOCAL_PATH)/core/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/preprocess/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/util/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_MODULE := imageproc
#LOCAL_LDLIBS := -landroid
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
为jni代码编写Application.mk
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION=4.8
APP_CPPFLAGS := -frtti -std=c++11 -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-8
第四部
进行ndk编译生成库。
第五步
在Anroid中编写调用的代码
首先声明接口函数
public static native byte[] ImageProc(String sdpath,String logpath, String imgpath, String svmpath, String annpath);
其中 sdpath 为外部sd卡路径,识别库过程中的一些文件会写入sd卡根目录下的/ai/tmp/路径下,故须传入,在Anroid中可通过Environment.getExternalStorageDirectory().getAbsolutePath()获取
logpath为识别的日志文件存储路径,一般放在sd开的ai目录下,比如"/sdcard/ai/"
imgpath为待识别的图片的路径
svmpath为车牌检测svm.xml资源的存放路径。现在程序做了一个功能,首次安装或者升级,都会将需要用到的svm.xml和ann.xml从程序的assets目录下拷贝到sd卡的ai目录下,故一般该路径为"/sdcard/svm.xml"
annpath为车牌识别ann.xml资源的存放路径。一般该路径为"/sdcard/ann.xml"
java代码如下
String resultImgDirPath = path +"/ai/tmp/";
String logpath = path+"/ai/ai_log.log";
String svmpath = path+"/ai/svm.xml";
String annpath = path+"/ai/ann.xml";
String imagepath = new String(imgpath.getBytes(),"gbk");
System.out.println("entering the jni");
SendMsgText("正在识别.....",1);
Thread.sleep(100);
String result = null;
byte[] resultByte =CarPlateDetection.ImageProc(path, logpath, imagepath, svmpath, annpath);
System.out.println(result);
if(resultByte != null)
{
bmp = BitmapFactory.decodeFile(resultImgDirPath+"result.jpg");
SendMsgRefresh(3);
result = new String(resultByte,"UTF-8");
SendMsgText(result,1);
SendMsgText(result,2);
}
else
{
SendMsgText("识别失败!",1);
}
目前写的比较简单,以后再完善吧,更多可查看代码实现。效果图如下