提交Android版实时识别功能

This commit is contained in:
iss
2019-07-24 17:00:09 +08:00
parent 74a7bdf649
commit 581d93e99c
462 changed files with 785 additions and 95 deletions
+2
View File
@@ -50,6 +50,8 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".CameraActivity"
/>
</application>
</manifest>
+1 -2
View File
@@ -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)
View File
View File
@@ -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<std::string> plateRes;
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat plateImage,int method);
};
}
#endif //SWIFTPR_PIPLINE_H
+130 -5
View File
@@ -2,7 +2,74 @@
#include <string>
#include "include/Pipeline.h"
#include <android/log.h>
#include <android/bitmap.h>
#include <opencv2/opencv.hpp>
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<pr::PlateInfo> list_res= PR->RunPiplineAsImage(rgb,1);
std::vector<pr::PlateInfo> list_res= PR->RunPiplineAsImage(rgb,pr::SEGMENTATION_FREE_METHOD);
// std::vector<pr::PlateInfo> 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,"<init>","()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<pr::PlateInfo> 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,
View File
@@ -0,0 +1,126 @@
//
// Created by 庾金科 on 20/09/2017.
//
#ifndef SWIFTPR_PLATEINFO_H
#define SWIFTPR_PLATEINFO_H
#include <opencv2/opencv.hpp>
namespace pr {
typedef std::vector<cv::Mat> Character;
enum PlateColor { BLUE, YELLOW, WHITE, GREEN, BLACK,UNKNOWN};
enum CharType {CHINESE,LETTER,LETTER_NUMS,INVALID};
class PlateInfo {
public:
std::vector<std::pair<CharType,cv::Mat>> plateChars;
std::vector<std::pair<CharType,cv::Mat>> 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<CharType,cv::Mat> &plateChar)
{
plateChars.push_back(plateChar);
}
void appendPlateCoding(const std::pair<CharType,cv::Mat> &charProb){
plateCoding.push_back(charProb);
}
// cv::Mat getPlateChars(int id) {
// if(id<PlateChars.size())
// return PlateChars[id];
// }
std::string decodePlateNormal(std::vector<std::string> 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)<<std::endl;
}
else if(plate.first == LETTER) {
decode += mappingTable[std::max_element(prob+41,prob+65)- prob];
confidence+=*std::max_element(prob+41,prob+65);
}
else if(plate.first == LETTER_NUMS) {
decode += mappingTable[std::max_element(prob+31,prob+65)- prob];
confidence+=*std::max_element(prob+31,prob+65);
// std::cout<<*std::max_element(prob+31,prob+65)<<std::endl;
}
else if(plate.first == INVALID)
{
decode+='*';
}
}
name = decode;
confidence/=7;
return decode;
}
private:
cv::Mat licensePlate;
cv::Rect ROI;
std::string name ;
PlateColor Type;
};
}
#endif //SWIFTPR_PLATEINFO_H

Some files were not shown because too many files have changed in this diff Show More