更新到HyperLPR3版本

This commit is contained in:
tunmx
2023-02-27 15:47:55 +08:00
parent 7ae4d385e1
commit 0864e05f76
912 changed files with 8160 additions and 221461 deletions
+1
View File
@@ -0,0 +1 @@
/build
+47
View File
@@ -0,0 +1,47 @@
plugins {
id 'com.android.library'
}
android {
compileSdk 31
defaultConfig {
minSdk 22
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
ndk { abiFilters "armeabi-v7a", "arm64-v8a" }
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
assets.srcDirs = ['src/main/assets']
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,26 @@
package com.hyperai.hyperlpr3;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.hyperai.hyperlpr3.test", appContext.getPackageName());
}
}
@@ -0,0 +1,64 @@
package com.hyperai.hyperlpr3;
import android.content.Context;
import android.util.Log;
import com.hyperai.hyperlpr3.api.APIDefine;
import com.hyperai.hyperlpr3.bean.Parameter;
import com.hyperai.hyperlpr3.bean.Plate;
import com.hyperai.hyperlpr3.core.HyperLPRCore;
import com.hyperai.hyperlpr3.settings.TypeDefine;
import com.hyperai.hyperlpr3.settings.SDKConfig;
import com.hyperai.hyperlpr3.utils.SDKUtils;
public class HyperLPR3 extends TypeDefine implements APIDefine {
private final String TAG = "HyperLPR3";
private final HyperLPRCore mCore;
private final Context mContext;
public HyperLPR3(Context mContext, Parameter parameter) {
this.mContext = mContext;
String mResourceFolderPath = mContext.getExternalFilesDir(null).getAbsolutePath() + "/";
SDKUtils.copyFilesFromAssets(mContext, SDKConfig.packDirName, mResourceFolderPath);
Log.i(TAG, "resource: " + mResourceFolderPath);
if (parameter.getModelPath() == null || "".equals(parameter.getModelPath())) {
parameter.setModelPath(mResourceFolderPath);
}
mCore = new HyperLPRCore();
mCore.createRecognizerContext(parameter);
}
public Context getContext() {
return mContext;
}
public void release() {
mCore.release();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
release();
}
/**
* License plate recognition interface.
*
* @param buf Image data buffer.
* @param height Height of the image
* @param width Width of the image
* @param rotation Original data buffer rotation Angle
* @param format Buffer data coded format
* @return Resulting object array
*/
@Override
public Plate[] plateRecognition(byte[] buf, int height, int width, int rotation, int format) {
return mCore.plateRecognitionFromBuffer(buf, height, width, rotation, format);
}
}
@@ -0,0 +1,18 @@
package com.hyperai.hyperlpr3.api;
import com.hyperai.hyperlpr3.bean.Plate;
public interface APIDefine {
/**
* License plate recognition interface.
* @param buf Image data buffer.
* @param height Height of the image
* @param width Width of the image
* @param rotation Original data buffer rotation Angle
* @param format Buffer data coded format
* @return Resulting object array
*/
Plate[] plateRecognition(byte[] buf, int height, int width, int rotation, int format);
}
@@ -0,0 +1,89 @@
package com.hyperai.hyperlpr3.bean;
import com.hyperai.hyperlpr3.settings.TypeDefine;
public class Parameter {
private String modelPath;
private int threads = 1;
private boolean useHalf = true;
private float boxConfThreshold = 0.25f;
private float nmsThreshold = 0.6f;
private float recConfidenceThreshold = 0.75f;
private int detLevel = TypeDefine.DETECT_LEVEL_LOW;
private int maxNum = 3;
public Parameter() {
}
public int getMaxNum() {
return maxNum;
}
public void setMaxNum(int maxNum) {
this.maxNum = maxNum;
}
public String getModelPath() {
return modelPath;
}
public void setModelPath(String modelPath) {
this.modelPath = modelPath;
}
public int getThreads() {
return threads;
}
public void setThreads(int threads) {
this.threads = threads;
}
public boolean isUseHalf() {
return useHalf;
}
public void setUseHalf(boolean useHalf) {
this.useHalf = useHalf;
}
public float getBoxConfThreshold() {
return boxConfThreshold;
}
public void setBoxConfThreshold(float boxConfThreshold) {
this.boxConfThreshold = boxConfThreshold;
}
public float getNmsThreshold() {
return nmsThreshold;
}
public void setNmsThreshold(float nmsThreshold) {
this.nmsThreshold = nmsThreshold;
}
public float getRecConfidenceThreshold() {
return recConfidenceThreshold;
}
public void setRecConfidenceThreshold(float recConfidenceThreshold) {
this.recConfidenceThreshold = recConfidenceThreshold;
}
public int getDetLevel() {
return detLevel;
}
public void setDetLevel(int detLevel) {
this.detLevel = detLevel;
}
}
@@ -0,0 +1,89 @@
package com.hyperai.hyperlpr3.bean;
public class Plate {
private float x1;
private float y1;
private float x2;
private float y2;
private int type;
private float confidence;
private String code;
public Plate() {};
public float getX1() {
return x1;
}
public void setX1(float x1) {
this.x1 = x1;
}
public float getY1() {
return y1;
}
public void setY1(float y1) {
this.y1 = y1;
}
public float getX2() {
return x2;
}
public void setX2(float x2) {
this.x2 = x2;
}
public float getY2() {
return y2;
}
public void setY2(float y2) {
this.y2 = y2;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public float getConfidence() {
return confidence;
}
public void setConfidence(float confidence) {
this.confidence = confidence;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "Plate{" +
"x1=" + x1 +
", y1=" + y1 +
", x2=" + x2 +
", y2=" + y2 +
", type=" + type +
", confidence=" + confidence +
", code='" + code + '\'' +
'}';
}
}
@@ -0,0 +1,53 @@
package com.hyperai.hyperlpr3.core;
import android.util.Log;
import com.hyperai.hyperlpr3.bean.Parameter;
import com.hyperai.hyperlpr3.bean.Plate;
public class HyperLPRCore {
final String TAG = "HyperLPRCore";
static {
System.loadLibrary("hyperlpr3");
}
private long ctxHandle_;
private boolean isRunning_;
// public void testBuffer(String savePath, byte[] buf, int height, int width, int rotation) {
// TestBuffer(savePath, buf, height, width, rotation);
// }
public void createRecognizerContext(Parameter parameter) {
ctxHandle_ = CreateRecognizerContext(parameter);
Log.i(TAG, "HANDLE: " + ctxHandle_);
isRunning_ = true;
}
public Plate[] plateRecognitionFromBuffer(byte[] buf, int height, int width, int rotation, int format) {
return PlateRecognitionFromBuffer(ctxHandle_, buf, height, width, rotation, format);
}
public int release() {
int ret = -1;
if (isRunning_) {
ret = ReleaseRecognizerContext(ctxHandle_);
isRunning_ = false;
ctxHandle_ = 0;
}
return ret;
}
// ===================Native==================
// native void TestBuffer(String savePath, byte[] buf, int height, int width, int rotation);
native long CreateRecognizerContext(Parameter parameterObj);
native int ReleaseRecognizerContext(long handle);
native Plate[] PlateRecognitionFromBuffer(long handle, byte[] buf, int height, int width, int rotation, int format);
}
@@ -0,0 +1,7 @@
package com.hyperai.hyperlpr3.settings;
public class SDKConfig {
public static final String packDirName = "r2_mobile";
}
@@ -0,0 +1,54 @@
package com.hyperai.hyperlpr3.settings;
public class TypeDefine {
/** 四种情况的转角 */
public static final int CAMERA_ROTATION_0 = 0;
public static final int CAMERA_ROTATION_90 = 1;
public static final int CAMERA_ROTATION_180 = 2;
public static final int CAMERA_ROTATION_270 = 3;
/** 低开销检测模式 */
public static final int DETECT_LEVEL_LOW = 0;
/** 高开销检测模式 */
public static final int DETECT_LEVEL_HIGH = 1;
/** Image in RGB format - RGB排列格式的图像 */
public static final int STREAM_RGB = 0;
/** Image in BGR format (Opencv Mat default) - BGR排列格式的图像(OpenCV的Mat默认) */
public static final int STREAM_BGR = 1;
/** Image in RGB with alpha channel format -带alpha通道的RGB排列格式的图像 */
public static final int STREAM_RGBA = 2;
/** Image in BGR with alpha channel format -带alpha通道的BGR排列格式的图像 */
public static final int STREAM_BGRA = 3;
/** Image in YUV NV12 format - YUV NV12排列的图像格式 */
public static final int STREAM_YUV_NV12 = 4;
/** Image in YUV NV21 format - YUV NV21排列的图像格式 */
public static final int STREAM_YUV_NV21 = 5;
/** 未知车牌 */
public static final int PLATE_TYPE_UNKNOWN = -1;
/** 蓝牌 */
public static final int PLATE_TYPE_BLUE = 0;
/** 黄牌单层 */
public static final int PLATE_TYPE_YELLOW_SINGLE = 1;
/** 白牌单层 */
public static final int PLATE_TYPE_WHILE_SINGLE = 2;
/** 绿牌新能源 */
public static final int PLATE_TYPE_GREEN = 3;
/** 黑牌港澳 */
public static final int PLATE_TYPE_BLACK_HK_MACAO = 4;
/** 香港单层 */
public static final int PLATE_TYPE_HK_SINGLE = 5;
/** 香港双层 */
public static final int PLATE_TYPE_HK_DOUBLE = 6;
/** 澳门单层 */
public static final int PLATE_TYPE_MACAO_SINGLE = 7;
/** 澳门双层 */
public static final int PLATE_TYPE_MACAO_DOUBLE = 8;
/** 黄牌双层 */
public static final int PLATE_TYPE_YELLOW_DOUBLE = 9;
public static final String[] PLATE_TYPE_MAPS = {"蓝牌", "黄牌单层", "白牌单层", "绿牌新能源", "黑牌港澳", "香港单层", "香港双层", "澳门单层", "澳门双层", "黄牌双层"};
}
@@ -0,0 +1,129 @@
package com.hyperai.hyperlpr3.utils;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class SDKUtils {
static public void copyFilesFromAssets(Context context, String oldPath, String newPath) {
try {
String[] fileNames = context.getAssets().list(oldPath);
if (fileNames.length > 0) {
// directory
File file = new File(newPath);
if (!file.mkdir()) {
Log.d("mkdir", "can't make folder");
}
// return false; // copy recursively
for (String fileName : fileNames) {
copyFilesFromAssets(context, oldPath + "/" + fileName,
newPath + "/" + fileName);
}
} else {
// file
InputStream is = context.getAssets().open(oldPath);
FileOutputStream fos = new FileOutputStream(new File(newPath));
byte[] buffer = new byte[1024];
int byteCount;
while ((byteCount = is.read(buffer)) != -1) {
fos.write(buffer, 0, byteCount);
}
fos.flush();
is.close();
fos.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static public void mkdirsFeaturesAssets(Context context, String path, String images, String features) {
try {
File file = new File(path);
File imagePath = new File(path + images);
File featurePath = new File(path + features);
if (!file.mkdir()) {
Log.d("mkdir", "can't make folder: " + file);
}
if (!imagePath.mkdir()) {
Log.d("mkdir", "can't make folder: " + imagePath);
}
if (!featurePath.mkdir()) {
Log.d("mkdir", "can't make folder: " + featurePath);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static public String saveBitmap(String savePath, String name, Bitmap bitmap) throws IOException {
File f = new File(savePath, name + ".png");
if (f.exists()) {
f.delete();
}
FileOutputStream out = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
return f.getAbsolutePath();
}
static public boolean cropperBitmap(Bitmap bitmap, int[] rePoints, String sdcardPath, String name) {
int newWidth = 160;
int newHeight = 192;
float scaleWidth = ((float) newWidth) / bitmap.getWidth();
float scaleHeight = ((float) newHeight) / bitmap.getHeight();
Matrix matrix = new Matrix();
// matrix.postTranslate()
matrix.postScale(scaleWidth, scaleHeight);
matrix.setScale(-1, 1);
int px = Math.max(0, rePoints[0]);
int py = Math.max(0, rePoints[1]);
int w = rePoints[2] - px;
int h = rePoints[3] - py;
int pw = (bitmap.getWidth() - w > 0) ? w - 1 : bitmap.getWidth() - 1;
int ph = (bitmap.getHeight() - h > 0) ? h - 1 : bitmap.getHeight() - 1;
try {
Bitmap crop = Bitmap.createBitmap(bitmap, px, py, pw, ph, matrix, true);
// String sdcardPath = Environment.getExternalStorageDirectory() + File.separator + Const.root + Const.save + Const.images;
saveBitmap(sdcardPath, name, crop);
} catch (Exception err) {
Log.d("crop", "ext");
return false;
}
return true;
}
public static Bitmap getImageFromAssetsFile(Context context, String fileName) {
Bitmap image = null;
AssetManager am = context.getResources().getAssets();
try {
InputStream is = am.open(fileName);
image = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
}
@@ -0,0 +1,17 @@
package com.hyperai.hyperlpr3;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}