diff --git a/Prj-Android/app/.gitignore b/Prj-Android/app/.gitignore old mode 100644 new mode 100755 index 9bea547..e072d26 --- a/Prj-Android/app/.gitignore +++ b/Prj-Android/app/.gitignore @@ -1,4 +1,5 @@ *.iml +app.iml .gradle /local.properties /.idea/libraries diff --git a/Prj-Android/app/CMakeLists.txt b/Prj-Android/app/CMakeLists.txt index 7c47806..76ab34a 100755 --- a/Prj-Android/app/CMakeLists.txt +++ b/Prj-Android/app/CMakeLists.txt @@ -4,4 +4,4 @@ # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) -add_subdirectory(src/main/cpp) \ No newline at end of file +add_subdirectory(src/main/cpp) diff --git a/Prj-Android/app/app.iml b/Prj-Android/app/app.iml old mode 100644 new mode 100755 index 88f982e..82d9eee --- a/Prj-Android/app/app.iml +++ b/Prj-Android/app/app.iml @@ -8,7 +8,7 @@ - @@ -22,7 +22,8 @@ @@ -35,14 +36,12 @@ - - @@ -96,10 +95,12 @@ + + + - @@ -108,10 +109,9 @@ - + - @@ -129,34 +129,36 @@ - + + + + - - - + + + + + + - - - - + + - - - + - - - + + - + + + - \ No newline at end of file diff --git a/Prj-Android/app/build.gradle b/Prj-Android/app/build.gradle old mode 100644 new mode 100755 index 8d190ef..59b7e2f --- a/Prj-Android/app/build.gradle +++ b/Prj-Android/app/build.gradle @@ -59,5 +59,7 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + api 'com.github.bumptech.glide:glide:3.8.0' + implementation 'org.greenrobot:eventbus:3.0.0' implementation project(':openCVLibrary342') } \ No newline at end of file diff --git a/Prj-Android/app/proguard-rules.pro b/Prj-Android/app/proguard-rules.pro old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/AndroidManifest.xml b/Prj-Android/app/src/main/AndroidManifest.xml old mode 100644 new mode 100755 index baf8769..00d4fb5 --- a/Prj-Android/app/src/main/AndroidManifest.xml +++ b/Prj-Android/app/src/main/AndroidManifest.xml @@ -50,6 +50,8 @@ + \ No newline at end of file diff --git a/Prj-Android/app/src/main/cpp/CMakeLists.txt b/Prj-Android/app/src/main/cpp/CMakeLists.txt index 17f3bfe..46848ed 100755 --- a/Prj-Android/app/src/main/cpp/CMakeLists.txt +++ b/Prj-Android/app/src/main/cpp/CMakeLists.txt @@ -38,8 +38,7 @@ add_library( # Sets the name of the library. #target_link_libraries( hyperlpr lib_opencv) -target_link_libraries(hyperlpr ${OpenCV_LIBS}) - +target_link_libraries(hyperlpr jnigraphics ${OpenCV_LIBS}) #连接现成的第三方库 #set(INC_DIR /Users/mac02/Desktop/studiospace/test/PrjAnndroid/app/src/main/cpp/OpencvNative/include) diff --git a/Prj-Android/app/src/main/cpp/Makefile b/Prj-Android/app/src/main/cpp/Makefile old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/cmake_install.cmake b/Prj-Android/app/src/main/cpp/cmake_install.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/include/Pipeline.h b/Prj-Android/app/src/main/cpp/include/Pipeline.h index ecbee61..c32976b 100755 --- a/Prj-Android/app/src/main/cpp/include/Pipeline.h +++ b/Prj-Android/app/src/main/cpp/include/Pipeline.h @@ -21,8 +21,6 @@ namespace pr{ "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z","港","学","使","警","澳","挂","军","北","南","广","沈","兰","成","济","海","民","航","空"}; - - const int SEGMENTATION_FREE_METHOD = 0; const int SEGMENTATION_BASED_METHOD = 1; @@ -37,24 +35,14 @@ namespace pr{ PipelinePR(std::string detector_filename, std::string finemapping_prototxt,std::string finemapping_caffemodel, std::string segmentation_prototxt,std::string segmentation_caffemodel, - std::string charRecognization_proto,std::string charRecognization_caffemodel); -// std::string segmentationfree_proto,std::string segmentationfree_caffemodel -// ); + std::string charRecognization_proto,std::string charRecognization_caffemodel, + std::string segmentationfree_proto,std::string segmentationfree_caffemodel + ); ~PipelinePR(); - - std::vector plateRes; std::vector RunPiplineAsImage(cv::Mat plateImage,int method); - - - - - - }; - - } #endif //SWIFTPR_PIPLINE_H diff --git a/Prj-Android/app/src/main/cpp/javaWarpper.cpp b/Prj-Android/app/src/main/cpp/javaWarpper.cpp old mode 100644 new mode 100755 index a236a5c..24f81fd --- a/Prj-Android/app/src/main/cpp/javaWarpper.cpp +++ b/Prj-Android/app/src/main/cpp/javaWarpper.cpp @@ -2,7 +2,74 @@ #include #include "include/Pipeline.h" - +#include +#include + +#include + +using namespace cv; +#define LOG_TAG "System.out" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) +jobject mat_to_bitmap(JNIEnv * env, Mat & src, bool needPremultiplyAlpha, jobject bitmap_config){ + + jclass java_bitmap_class = (jclass)env->FindClass("android/graphics/Bitmap"); + jmethodID mid = env->GetStaticMethodID(java_bitmap_class, + "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;"); + + jobject bitmap = env->CallStaticObjectMethod(java_bitmap_class, + mid, src.size().width, src.size().height, bitmap_config); + AndroidBitmapInfo info; + void* pixels = 0; + + try { + //validate + CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0); + CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4); + CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0); + CV_Assert(pixels); + + //type mat + if(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888){ + Mat tmp(info.height, info.width, CV_8UC4, pixels); + if(src.type() == CV_8UC1){ + cvtColor(src, tmp, CV_GRAY2RGBA); + } else if(src.type() == CV_8UC3){ + cvtColor(src, tmp, CV_RGB2RGBA); + } else if(src.type() == CV_8UC4){ + if(needPremultiplyAlpha){ + cvtColor(src, tmp, COLOR_RGBA2mRGBA); + }else{ + src.copyTo(tmp); + } + } + + } else{ + Mat tmp(info.height, info.width, CV_8UC2, pixels); + if(src.type() == CV_8UC1){ + cvtColor(src, tmp, CV_GRAY2BGR565); + } else if(src.type() == CV_8UC3){ + cvtColor(src, tmp, CV_RGB2BGR565); + } else if(src.type() == CV_8UC4){ + cvtColor(src, tmp, CV_RGBA2BGR565); + } + } + AndroidBitmap_unlockPixels(env, bitmap); + return bitmap; + } catch(cv::Exception e){ + AndroidBitmap_unlockPixels(env, bitmap); + jclass je = env->FindClass("org/opencv/core/CvException"); + if(!je) je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, e.what()); + return bitmap; + } catch (...){ + AndroidBitmap_unlockPixels(env, bitmap); + jclass je = env->FindClass("java/lang/Exception"); + env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}"); + return bitmap; + } +} std::string jstring2str(JNIEnv* env, jstring jstr) { @@ -36,7 +103,8 @@ Java_pr_platerecognization_PlateRecognition_InitPlateRecognizer( jstring detector_filename, jstring finemapping_prototxt, jstring finemapping_caffemodel, jstring segmentation_prototxt, jstring segmentation_caffemodel, - jstring charRecognization_proto, jstring charRecognization_caffemodel) { + jstring charRecognization_proto, jstring charRecognization_caffemodel, + jstring segmentationfree_proto, jstring segmentationfree_caffemodel) { std::string detector_path = jstring2str(env, detector_filename); std::string finemapping_prototxt_path = jstring2str(env, finemapping_prototxt); @@ -45,12 +113,15 @@ Java_pr_platerecognization_PlateRecognition_InitPlateRecognizer( std::string segmentation_caffemodel_path = jstring2str(env, segmentation_caffemodel); std::string charRecognization_proto_path = jstring2str(env, charRecognization_proto); std::string charRecognization_caffemodel_path = jstring2str(env, charRecognization_caffemodel); + std::string segmentationfree_proto_path = jstring2str(env, segmentationfree_proto); + std::string segmentationfree_caffemodel_path = jstring2str(env, segmentationfree_caffemodel); pr::PipelinePR *PR = new pr::PipelinePR(detector_path, finemapping_prototxt_path, finemapping_caffemodel_path, segmentation_prototxt_path, segmentation_caffemodel_path, - charRecognization_proto_path, charRecognization_caffemodel_path); + charRecognization_proto_path, charRecognization_caffemodel_path, + segmentationfree_proto_path, segmentationfree_caffemodel_path); return (jlong) PR; } @@ -63,25 +134,79 @@ Java_pr_platerecognization_PlateRecognition_SimpleRecognization( pr::PipelinePR *PR = (pr::PipelinePR *) object_pr; cv::Mat &mRgb = *(cv::Mat *) matPtr; cv::Mat rgb; -// cv::cvtColor(mRgb,rgb,cv::COLOR_RGBA2GRAY); cv::cvtColor(mRgb,rgb,cv::COLOR_RGBA2BGR); -// cv::imwrite("/sdcard/demo.jpg",rgb); //1表示SEGMENTATION_BASED_METHOD在方法里有说明 - std::vector list_res= PR->RunPiplineAsImage(rgb,1); + std::vector list_res= PR->RunPiplineAsImage(rgb,pr::SEGMENTATION_FREE_METHOD); // std::vector list_res= PR->RunPiplineAsImage(rgb,1); std::string concat_results; for(auto one:list_res) { + //可信度 if (one.confidence>0.7) concat_results+=one.getPlateName()+","; } + concat_results = concat_results.substr(0,concat_results.size()-1); return env->NewStringUTF(concat_results.c_str()); } + +/** + * 车牌号的详细信息 + * @param env + * @param obj + * @param matPtr + * @param object_pr + * @return + */ +JNIEXPORT jobject JNICALL +Java_pr_platerecognization_PlateRecognition_PlateInfoRecognization( + JNIEnv *env, jobject obj, + jlong matPtr, jlong object_pr) { + jclass plateInfo_class = env -> FindClass("pr/platerecognization/PlateInfo"); + jmethodID mid = env->GetMethodID(plateInfo_class,"","()V"); + jobject plateInfoObj = env->NewObject(plateInfo_class,mid); + + pr::PipelinePR *PR = (pr::PipelinePR *) object_pr; + cv::Mat &mRgb = *(cv::Mat *) matPtr; + cv::Mat rgb; + cv::cvtColor(mRgb,rgb,cv::COLOR_RGBA2BGR); + + //1表示SEGMENTATION_BASED_METHOD在方法里有说明 + std::vector list_res= PR->RunPiplineAsImage(rgb,pr::SEGMENTATION_FREE_METHOD); + std::string concat_results; + pr::PlateInfo plateInfo; + for(auto one:list_res) + { + //可信度 + if (one.confidence>0.7) { + plateInfo = one; + //车牌号 + jfieldID fid_plate_name = env->GetFieldID(plateInfo_class,"plateName","Ljava/lang/String;"); + env->SetObjectField(plateInfoObj,fid_plate_name,env->NewStringUTF(plateInfo.getPlateName().c_str())); + + //识别区域 + Mat src = plateInfo.getPlateImage(); + + jclass java_bitmap_class = (jclass)env->FindClass("android/graphics/Bitmap$Config"); + jmethodID bitmap_mid = env->GetStaticMethodID(java_bitmap_class, + "nativeToConfig", "(I)Landroid/graphics/Bitmap$Config;"); + jobject bitmap_config = env->CallStaticObjectMethod(java_bitmap_class, bitmap_mid, 5); + + jfieldID fid_bitmap = env->GetFieldID(plateInfo_class, "bitmap","Landroid/graphics/Bitmap;"); + jobject _bitmap = mat_to_bitmap(env, src, false, bitmap_config); + env->SetObjectField(plateInfoObj,fid_bitmap, _bitmap); + return plateInfoObj; + } + } + return plateInfoObj; + +} + + JNIEXPORT void JNICALL Java_pr_platerecognization_PlateRecognition_ReleasePlateRecognizer( JNIEnv *env, jobject obj, diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libIlmImf.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libIlmImf.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libcpufeatures.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libcpufeatures.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibjasper.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibjasper.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibjpeg-turbo.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibjpeg-turbo.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibpng.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibpng.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibprotobuf.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibprotobuf.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibtiff.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibtiff.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibwebp.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/liblibwebp.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libtbb.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libtbb.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libtegra_hal.a b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/3rdparty/libs/armeabi-v7a/libtegra_hal.a old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCV-armeabi-v7a.mk b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCV-armeabi-v7a.mk old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCV.mk b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCV.mk old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCVConfig-version.cmake b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCVConfig-version.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCVConfig.cmake b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/OpenCVConfig.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVConfig-version.cmake b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVConfig-version.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVConfig.cmake b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVConfig.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVModules-release.cmake b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVModules-release.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVModules.cmake b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/abi-armeabi-v7a/OpenCVModules.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/android.toolchain.cmake b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/android.toolchain.cmake old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cv.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cv.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cv.hpp b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cv.hpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cvaux.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cvaux.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cvaux.hpp b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cvaux.hpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cvwimage.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cvwimage.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxcore.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxcore.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxcore.hpp b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxcore.hpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxeigen.hpp b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxeigen.hpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxmisc.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/cxmisc.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/highgui.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/highgui.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/ml.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv/ml.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/calib3d.hpp b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/calib3d.hpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/calib3d/calib3d.hpp b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/calib3d/calib3d.hpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/calib3d/calib3d_c.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/calib3d/calib3d_c.h old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/core.hpp b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/core.hpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/core/PlateInfo.h b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/core/PlateInfo.h new file mode 100755 index 0000000..f500bb5 --- /dev/null +++ b/Prj-Android/app/src/main/cpp/opencv342/sdk/native/jni/include/opencv2/core/PlateInfo.h @@ -0,0 +1,126 @@ +// +// Created by 庾金科 on 20/09/2017. +// + +#ifndef SWIFTPR_PLATEINFO_H +#define SWIFTPR_PLATEINFO_H +#include +namespace pr { + + typedef std::vector Character; + + enum PlateColor { BLUE, YELLOW, WHITE, GREEN, BLACK,UNKNOWN}; + enum CharType {CHINESE,LETTER,LETTER_NUMS,INVALID}; + + + class PlateInfo { + public: + std::vector> plateChars; + std::vector> plateCoding; + float confidence = 0; + PlateInfo(const cv::Mat &plateData, std::string plateName, cv::Rect plateRect, PlateColor plateType) { + licensePlate = plateData; + name = plateName; + ROI = plateRect; + Type = plateType; + } + PlateInfo(const cv::Mat &plateData, cv::Rect plateRect, PlateColor plateType) { + licensePlate = plateData; + ROI = plateRect; + Type = plateType; + } + PlateInfo(const cv::Mat &plateData, cv::Rect plateRect) { + licensePlate = plateData; + ROI = plateRect; + } + PlateInfo() { + + } + + cv::Mat getPlateImage() { + return licensePlate; + } + + void setPlateImage(cv::Mat plateImage){ + licensePlate = plateImage; + } + + cv::Rect getPlateRect() { + return ROI; + } + + void setPlateRect(cv::Rect plateRect) { + ROI = plateRect; + } + cv::String getPlateName() { + return name; + + } + void setPlateName(cv::String plateName) { + name = plateName; + } + int getPlateType() { + return Type; + } + + void appendPlateChar(const std::pair &plateChar) + { + plateChars.push_back(plateChar); + } + + void appendPlateCoding(const std::pair &charProb){ + plateCoding.push_back(charProb); + } + + // cv::Mat getPlateChars(int id) { + // if(id mappingTable) { + std::string decode; + for(auto plate:plateCoding) { + float *prob = (float *)plate.second.data; + if(plate.first == CHINESE) { + + decode += mappingTable[std::max_element(prob,prob+31) - prob]; + confidence+=*std::max_element(prob,prob+31); + + +// std::cout<<*std::max_element(prob,prob+31)<FineMappingHorizon(image_finemapping, 4, HorizontalPadding+3); - cv::resize(image_finemapping, image_finemapping, cv::Size(136+HorizontalPadding, 36)); -// cv::imwrite("./test.png",image_finemapping); -// cv::imshow("image_finemapping",image_finemapping); -// cv::waitKey(0); plateinfo.setPlateImage(image_finemapping); -// std::vector rects; - std::pair res = segmentationFreeRecognizer->SegmentationFreeForSinglePlate(plateinfo.getPlateImage(),pr::CH_PLATE_CODE); plateinfo.confidence = res.second; plateinfo.setPlateName(res.first); diff --git a/Prj-Android/app/src/main/cpp/src/PlateDetection.cpp b/Prj-Android/app/src/main/cpp/src/PlateDetection.cpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/src/PlateSegmentation.cpp b/Prj-Android/app/src/main/cpp/src/PlateSegmentation.cpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/src/Recognizer.cpp b/Prj-Android/app/src/main/cpp/src/Recognizer.cpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/cpp/src/SegmentationFreeRecognizer.cpp b/Prj-Android/app/src/main/cpp/src/SegmentationFreeRecognizer.cpp old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/java/pr/platerecognization/CameraActivity.java b/Prj-Android/app/src/main/java/pr/platerecognization/CameraActivity.java new file mode 100755 index 0000000..64986b3 --- /dev/null +++ b/Prj-Android/app/src/main/java/pr/platerecognization/CameraActivity.java @@ -0,0 +1,91 @@ +package pr.platerecognization; + +import android.app.Activity; +import android.media.Image; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + + +/** + * @author by hs-johnny + * Created on 2019/6/17 + */ +public class CameraActivity extends Activity implements View.OnClickListener { + + FrameLayout previewFl; + CameraPreviews cameraPreview; + TextView plateTv; + TextView regTv; + ImageView image; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + setContentView(R.layout.activity_camera); + } + + private void initCamera(){ + previewFl = findViewById(R.id.preview_fl); + plateTv = findViewById(R.id.plate_tv); + regTv = findViewById(R.id.reg_tv); + regTv.setOnClickListener(this); + image = findViewById(R.id.image); + cameraPreview = new CameraPreviews(this); + previewFl.addView(cameraPreview); + } + + @Override + protected void onResume() { + super.onResume(); + if(cameraPreview == null){ + initCamera(); + } + } + + @Override + protected void onPause() { + super.onPause(); + cameraPreview = null; + } + + private void stopPreview(){ + previewFl.removeAllViews(); + } + + @Override + protected void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + } + + @Override + protected void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(PlateInfo plate){ + plateTv.setText(plate.plateName); + image.setImageBitmap(plate.bitmap); + stopPreview(); + } + + @Override + public void onClick(View v) { + CameraPreviews cameraPreview = new CameraPreviews(this); + previewFl.addView(cameraPreview); + } +} diff --git a/Prj-Android/app/src/main/java/pr/platerecognization/CameraPreviews.java b/Prj-Android/app/src/main/java/pr/platerecognization/CameraPreviews.java new file mode 100755 index 0000000..310867a --- /dev/null +++ b/Prj-Android/app/src/main/java/pr/platerecognization/CameraPreviews.java @@ -0,0 +1,269 @@ +package pr.platerecognization; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.YuvImage; +import android.hardware.Camera; +import android.media.Image; +import android.os.Handler; +import android.os.HandlerThread; +import android.support.v4.content.ContextCompat; +import android.text.TextUtils; +import android.util.Log; +import android.view.Display; +import android.view.MotionEvent; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; + +import org.greenrobot.eventbus.EventBus; +import org.opencv.core.Mat; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.Policy; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author by hs-johnny + * Created on 2019/6/17 + */ +public class CameraPreviews extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback { + + private static final String TAG = "CameraPreview"; + private Camera mCamera; + private SurfaceHolder mHolder; + public long handle; + private byte[] lock = new byte[0]; + private List mResultList = new ArrayList<>(); + private String currentPlate = ""; + private Paint mPaint; + private float oldDist = 1f; + /** 停止识别*/ + private boolean isStopReg; + + public CameraPreviews(Context context) { + super(context); + mHolder = getHolder(); + mHolder.addCallback(this); + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setStrokeWidth(2); + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setColor(ContextCompat.getColor(context, R.color.colorAccent)); + } + public Camera getCameraInstance(){ + if (mCamera == null){ + try { + CameraHandlerThread mThread = new CameraHandlerThread("camera thread"); + synchronized (mThread){ + mThread.openCamera(); + } + }catch (Exception e){ + Log.e(TAG, "camera is not available" ); + } + } + return mCamera; + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + mCamera = getCameraInstance(); + mCamera.setPreviewCallback(this); + try { + mCamera.setPreviewDisplay(mHolder); + mCamera.startPreview(); + setPreviewFocus(mCamera); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + int rotation = getDisplayOrientation(); + mCamera.setDisplayOrientation(rotation); + Camera.Parameters parameters = mCamera.getParameters(); + parameters.setRotation(rotation); + mCamera.setParameters(parameters); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + mHolder.removeCallback(this); + mCamera.setPreviewCallback(null); + mCamera.stopPreview(); + mCamera.release(); + mCamera = null; + } + + public int getDisplayOrientation(){ + Display display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + int rotation = display.getRotation(); + int degrees = 0; + switch (rotation){ + 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; + } + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info); + int result = (info.orientation - degrees + 360) % 360; + return result; + } + + @Override + public void onPreviewFrame(final byte[] data, final Camera camera) { + synchronized (lock){ + //处理data + Camera.Size previewSize = camera.getParameters().getPreviewSize(); + BitmapFactory.Options newOpts = new BitmapFactory.Options(); + newOpts.inJustDecodeBounds = true; + YuvImage yuvimage = new YuvImage( + data, + ImageFormat.NV21, + previewSize.width, + previewSize.height, + null); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos); + byte[] rawImage = baos.toByteArray(); + //将rawImage转换成bitmap + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.RGB_565; + Bitmap bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options); + PlateInfo result = MainActivity.simpleRecog(rotateBitmap(bitmap), 8); + bitmap.recycle(); + Log.e(TAG, "onPreviewFrame: "+result.plateName + "----time: "+ System.currentTimeMillis()); + if(!isStopReg && result != null && !TextUtils.isEmpty(result.plateName)) { + isStopReg = true; + sendPlate(result); + } + } + } + + private void sendPlate(PlateInfo plate){ + EventBus.getDefault().post(plate); + } + + private Bitmap rotateBitmap(Bitmap bmp){ + Matrix matrix = new Matrix(); + matrix.postRotate(90); + Bitmap rotatedBitMap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); + return rotatedBitMap; + } + + private void openCameraOriginal(){ + try { + mCamera = Camera.open(); + }catch (Exception e){ + Log.e(TAG, "camera is not available"); + } + } + + private class CameraHandlerThread extends HandlerThread { + Handler handler; + public CameraHandlerThread(String name) { + super(name); + start(); + handler = new Handler(getLooper()); + } + + synchronized void notifyCameraOpened(){ + notify(); + } + + void openCamera(){ + handler.post(new Runnable() { + @Override + public void run() { + openCameraOriginal(); + notifyCameraOpened(); + } + }); + try { + wait(); + }catch (Exception e){ + Log.e(TAG, "wait was interrupted"); + } + } + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if(event.getPointerCount() == 2){ + switch (event.getAction()){ + case MotionEvent.ACTION_POINTER_DOWN: + oldDist = getFingerSpacing(event); + break; + case MotionEvent.ACTION_MOVE: + float newDist = getFingerSpacing(event); + if(newDist > oldDist){ + handleZoom(true, mCamera); + }else if(newDist < oldDist){ + handleZoom(false, mCamera); + } + oldDist = newDist; + break; + } + } + return true; + } + + private float getFingerSpacing(MotionEvent event){ + float x = event.getX(0) - event.getX(1); + float y = event.getY(0) - event.getY(1); + return (float) Math.sqrt(x * x + y * y); + } + + private void handleZoom(boolean isZoomIn, Camera camera){ + Camera.Parameters parameters = camera.getParameters(); + if (parameters.isZoomSupported()){ + int maxZoom = parameters.getMaxZoom(); + int zoom = parameters.getZoom(); + if (isZoomIn && zoom < maxZoom){ + zoom++; + }else if(zoom > 0){ + zoom--; + } + parameters.setZoom(zoom); + camera.setParameters(parameters); + }else { + Log.e(TAG, "handleZoom: "+"the device is not support zoom"); + } + } + + private void setPreviewFocus(Camera camera){ + Camera.Parameters parameters = camera.getParameters(); + List focusList = parameters.getSupportedFocusModes(); + if(focusList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){ + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + } + camera.setParameters(parameters); + } +} diff --git a/Prj-Android/app/src/main/java/pr/platerecognization/MainActivity.java b/Prj-Android/app/src/main/java/pr/platerecognization/MainActivity.java index 916382b..36f78cb 100755 --- a/Prj-Android/app/src/main/java/pr/platerecognization/MainActivity.java +++ b/Prj-Android/app/src/main/java/pr/platerecognization/MainActivity.java @@ -19,7 +19,6 @@ import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.v4.app.ActivityCompat; -import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; @@ -27,7 +26,6 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; -import android.widget.Toast; import org.opencv.android.OpenCVLoader; import org.opencv.android.Utils; @@ -74,7 +72,7 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene // public PlateRecognition pr; - public long handle; + public static long handle; private final String TAG = this.getClass().toString(); @@ -138,11 +136,16 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene + File.separator+"CharacterRecognization.prototxt"; String character_caffemodel= sdcardPath + File.separator+"CharacterRecognization.caffemodel"; + String segmentationfree_prototxt = sdcardPath + + File.separator+"SegmenationFree-Inception.prototxt"; + String segmentationfree_caffemodel= sdcardPath + + File.separator+"SegmenationFree-Inception.caffemodel"; handle = PlateRecognition.InitPlateRecognizer( cascade_filename, finemapping_prototxt,finemapping_caffemodel, segmentation_prototxt,segmentation_caffemodel, - character_prototxt,character_caffemodel + character_prototxt,character_caffemodel, + segmentationfree_prototxt,segmentationfree_caffemodel ); @@ -175,8 +178,9 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene return cursor.getString(index); } } finally { - if (cursor != null) + if (cursor != null) { cursor.close(); + } } return null; } @@ -258,12 +262,11 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene return null; } - public void SimpleRecog(Bitmap bmp,int dp) + public void SimpleRecog(Bitmap bmp,int dp) { float dp_asp = dp/10.f; - imgv.setImageBitmap(bmp); -// Mat mat_src = new Mat(bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC1); +// imgv.setImageBitmap(bmp); Mat mat_src = new Mat(bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC4); float new_w = bmp.getWidth()*dp_asp; @@ -272,14 +275,41 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene Utils.bitmapToMat(bmp, mat_src); Imgproc.resize(mat_src,mat_src,sz); long currentTime1 = System.currentTimeMillis(); - String res = PlateRecognition.SimpleRecognization(mat_src.getNativeObjAddr(),handle); +// String res = PlateRecognition.SimpleRecognization(mat_src.getNativeObjAddr(),handle); +// resbox.setText("识别结果:"+res); + + PlateInfo plateInfo = PlateRecognition.PlateInfoRecognization(mat_src.getNativeObjAddr(),handle); + imgv.setImageBitmap(plateInfo.bitmap); + resbox.setText("识别结果:"+plateInfo.plateName); long diff = System.currentTimeMillis() - currentTime1; - resbox.setText("识别结果:"+res); + runtimebox.setText(String.valueOf(diff)+"ms"); } + + public static PlateInfo simpleRecog(Bitmap bmp,int dp) + { + + float dp_asp = dp/10.f; +// imgv.setImageBitmap(bmp); + Mat mat_src = new Mat(bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC4); + + float new_w = bmp.getWidth()*dp_asp; + float new_h = bmp.getHeight()*dp_asp; + Size sz = new Size(new_w,new_h); + Utils.bitmapToMat(bmp, mat_src); + Imgproc.resize(mat_src,mat_src,sz); + long currentTime1 = System.currentTimeMillis(); +// String res = PlateRecognition.SimpleRecognization(mat_src.getNativeObjAddr(),handle); +// resbox.setText("识别结果:"+res); + + PlateInfo plateInfo = PlateRecognition.PlateInfoRecognization(mat_src.getNativeObjAddr(),handle); + return plateInfo; + + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -296,7 +326,6 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene latestBitmap = bmp; SimpleRecog(bmp,sb.getProgress()); -// startOilPainting(bmp, file); } else if (requestCode == REQUEST_CODE_OP) { Log.i(TAG, "RESULT =" + resultCode); if (data == null) { @@ -332,6 +361,7 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene } btn = (Button)findViewById(R.id.button); recogBtn = (Button)findViewById(R.id.button_recog); + findViewById(R.id.button_recog_now).setOnClickListener(this); imgv = (ImageView)findViewById(R.id.imageView); resbox = (TextView)findViewById(R.id.textView); sb = (SeekBar)findViewById(R.id.seek); @@ -341,29 +371,6 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene initRecognizer(); btn.setOnClickListener(this); recogBtn.setOnClickListener(this); -// -// btn.setOnClickListener(new View.OnClickListener() { -// @Override -// public void onClick(View view) -// { -// -// -// Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.demo); -//// Bitmap bmp = imgv.setImageBitmap(); -// imgv.setImageBitmap(bmp); -// Mat mat_src = new Mat(bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC4); -// -// Size sz = new Size(720,682); -// Utils.bitmapToMat(bmp, mat_src); -// Imgproc.resize(mat_src,mat_src,sz); -// String res = PlateRecognition.SimpleRecognization(mat_src.getNativeObjAddr(),handle); -// resbox.setText("识别结果:"+res); -// -// } -// } -// ); - // Example of a call to a native method -// TextView tv = (TextView) findViewById(R.id); } @@ -406,6 +413,12 @@ public class MainActivity extends Activity implements AlertDialog.OnClickListene SimpleRecog(latestBitmap,sb.getProgress()); } break; + case R.id.button_recog_now: + Intent intent = new Intent(this, CameraActivity.class); + startActivity(intent); + break; + default: + break; } } } diff --git a/Prj-Android/app/src/main/java/pr/platerecognization/PlateInfo.java b/Prj-Android/app/src/main/java/pr/platerecognization/PlateInfo.java new file mode 100755 index 0000000..2abab7f --- /dev/null +++ b/Prj-Android/app/src/main/java/pr/platerecognization/PlateInfo.java @@ -0,0 +1,30 @@ +package pr.platerecognization; + +import android.graphics.Bitmap; + +import org.opencv.core.Mat; + +/** + * @author liuxuhui + * @date 2019/6/20 + */ +public class PlateInfo { + + /** + * 车牌号 + */ + public String plateName; + + /** + * 车牌号图片 + */ + public Bitmap bitmap; + + public PlateInfo() { + } + + public PlateInfo(String plateName, Bitmap bitmap) { + this.plateName = plateName; + this.bitmap = bitmap; + } +} diff --git a/Prj-Android/app/src/main/java/pr/platerecognization/PlateRecognition.java b/Prj-Android/app/src/main/java/pr/platerecognization/PlateRecognition.java index 5aadecb..e6f9a3c 100755 --- a/Prj-Android/app/src/main/java/pr/platerecognization/PlateRecognition.java +++ b/Prj-Android/app/src/main/java/pr/platerecognization/PlateRecognition.java @@ -11,9 +11,11 @@ public class PlateRecognition { static native long InitPlateRecognizer(String casacde_detection, String finemapping_prototxt,String finemapping_caffemodel, String segmentation_prototxt,String segmentation_caffemodel, - String charRecognization_proto,String charRecognization_caffemodel); + String charRecognization_proto,String charRecognization_caffemodel, + String segmentationfree_proto, String segmentationfree_caffemodel); static native void ReleasePlateRecognizer(long object); static native String SimpleRecognization(long inputMat,long object); + static native PlateInfo PlateInfoRecognization(long inputMat,long object); } diff --git a/Prj-Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Prj-Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/res/drawable/ic_launcher_background.xml b/Prj-Android/app/src/main/res/drawable/ic_launcher_background.xml old mode 100644 new mode 100755 diff --git a/Prj-Android/app/src/main/res/layout/activity_camera.xml b/Prj-Android/app/src/main/res/layout/activity_camera.xml new file mode 100755 index 0000000..20f07f3 --- /dev/null +++ b/Prj-Android/app/src/main/res/layout/activity_camera.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Prj-Android/app/src/main/res/layout/activity_main.xml b/Prj-Android/app/src/main/res/layout/activity_main.xml old mode 100644 new mode 100755 index 4038562..aa46ce3 --- a/Prj-Android/app/src/main/res/layout/activity_main.xml +++ b/Prj-Android/app/src/main/res/layout/activity_main.xml @@ -29,6 +29,15 @@ app:layout_constraintRight_toLeftOf="@id/button" /> +