diff --git a/src/app/build.gradle b/src/app/build.gradle index a2f506b..2bd5b47 100644 --- a/src/app/build.gradle +++ b/src/app/build.gradle @@ -7,9 +7,36 @@ android { defaultConfig { applicationId "my.wificar" minSdkVersion 21 + externalNativeBuild { + cmake { + cppFlags "" + arguments '-DANDROID_PLATFORM=android-24', '-DANDROID_STL=c++_static', '-DANDROID_STL=c++_shared' + } + } + ndk { + moduleName "WztNcnnJniLog" //编译后会生成 .so + ldLibs "log", "z", "m" + abiFilters "armeabi-v7a", "arm64-v8a" // opencv库太大只留需要的 + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + externalNativeBuild { + cmake { + path "src/main/cpp/CMakeLists.txt" + version "3.10.2" + } + } + sourceSets { + main { + jniLibs.srcDirs = ['src/main/jniLibs', 'libs'] // libs + } } - buildTypes { release { minifyEnabled false @@ -17,10 +44,18 @@ android { } } namespace 'my.wificar' + repositories { + flatDir { + dirs 'libs' + } + } } dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.15' + implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.15' } diff --git a/src/app/src/main/cpp/jni_interface.cpp b/src/app/src/main/cpp/jni_interface.cpp index 1e733a2..bc5d971 100644 --- a/src/app/src/main/cpp/jni_interface.cpp +++ b/src/app/src/main/cpp/jni_interface.cpp @@ -56,7 +56,7 @@ JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved) { Yolov5 ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_YOLOv5_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { +Java_wificar_YOLOv5_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { if (YoloV5::detector != nullptr) { delete YoloV5::detector; YoloV5::detector = nullptr; @@ -68,10 +68,10 @@ Java_com_wzt_yolov5_YOLOv5_init(JNIEnv *env, jclass, jobject assetManager, jbool } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_YOLOv5_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { +Java_wificar_YOLOv5_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { auto result = YoloV5::detector->detect(env, image, threshold, nms_threshold); - auto box_cls = env->FindClass("com/wzt/yolov5/Box"); + auto box_cls = env->FindClass("wificar/Box"); auto cid = env->GetMethodID(box_cls, "", "(FFFFIF)V"); jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); int i = 0; @@ -86,7 +86,7 @@ Java_com_wzt_yolov5_YOLOv5_detect(JNIEnv *env, jclass, jobject image, jdouble th // ***************************************[ Yolov5 Custom Layer ]**************************************** extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_YOLOv5_initCustomLayer(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { +Java_wificar_YOLOv5_initCustomLayer(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { if (YoloV5CustomLayer::detector != nullptr) { delete YoloV5CustomLayer::detector; YoloV5CustomLayer::detector = nullptr; @@ -98,10 +98,10 @@ Java_com_wzt_yolov5_YOLOv5_initCustomLayer(JNIEnv *env, jclass, jobject assetMan } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_YOLOv5_detectCustomLayer(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { +Java_wificar_YOLOv5_detectCustomLayer(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { auto result = YoloV5CustomLayer::detector->detect(env, image, threshold, nms_threshold); - auto box_cls = env->FindClass("com/wzt/yolov5/Box"); + auto box_cls = env->FindClass("wificar/Box"); auto cid = env->GetMethodID(box_cls, "", "(FFFFIF)V"); jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); int i = 0; @@ -124,7 +124,7 @@ Java_com_wzt_yolov5_YOLOv5_detectCustomLayer(JNIEnv *env, jclass, jobject image, // 20201124 澧炲姞 yolo-fastest-xl extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_YOLOv4_init(JNIEnv *env, jclass, jobject assetManager, jint yoloType, jboolean useGPU) { +Java_wificar_YOLOv4_init(JNIEnv *env, jclass, jobject assetManager, jint yoloType, jboolean useGPU) { if (YoloV4::detector != nullptr) { delete YoloV4::detector; YoloV4::detector = nullptr; @@ -143,10 +143,10 @@ Java_com_wzt_yolov5_YOLOv4_init(JNIEnv *env, jclass, jobject assetManager, jint } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_YOLOv4_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { +Java_wificar_YOLOv4_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { auto result = YoloV4::detector->detect(env, image, threshold, nms_threshold); - auto box_cls = env->FindClass("com/wzt/yolov5/Box"); + auto box_cls = env->FindClass("wificar/Box"); auto cid = env->GetMethodID(box_cls, "", "(FFFFIF)V"); jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); int i = 0; @@ -163,7 +163,7 @@ Java_com_wzt_yolov5_YOLOv4_detect(JNIEnv *env, jclass, jobject image, jdouble th NanoDet ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_NanoDet_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { +Java_wificar_NanoDet_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { if (NanoDet::detector != nullptr) { delete NanoDet::detector; NanoDet::detector = nullptr; @@ -175,10 +175,10 @@ Java_com_wzt_yolov5_NanoDet_init(JNIEnv *env, jclass, jobject assetManager, jboo } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_NanoDet_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { +Java_wificar_NanoDet_detect(JNIEnv *env, jclass, jobject image, jdouble threshold, jdouble nms_threshold) { auto result = NanoDet::detector->detect(env, image, threshold, nms_threshold); - auto box_cls = env->FindClass("com/wzt/yolov5/Box"); + auto box_cls = env->FindClass("wificar/Box"); auto cid = env->GetMethodID(box_cls, "", "(FFFFIF)V"); jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); int i = 0; @@ -197,7 +197,7 @@ Java_com_wzt_yolov5_NanoDet_detect(JNIEnv *env, jclass, jobject image, jdouble t ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_SimplePose_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { +Java_wificar_SimplePose_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { if (SimplePose::detector != nullptr) { delete SimplePose::detector; SimplePose::detector = nullptr; @@ -209,10 +209,10 @@ Java_com_wzt_yolov5_SimplePose_init(JNIEnv *env, jclass clazz, jobject assetMana } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_SimplePose_detect(JNIEnv *env, jclass clazz, jobject image) { +Java_wificar_SimplePose_detect(JNIEnv *env, jclass clazz, jobject image) { auto result = SimplePose::detector->detect(env, image); - auto box_cls = env->FindClass("com/wzt/yolov5/KeyPoint"); + auto box_cls = env->FindClass("wificar/KeyPoint"); auto cid = env->GetMethodID(box_cls, "", "([F[FFFFFF)V"); jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); int i = 0; @@ -272,7 +272,7 @@ jcharArray matToBitmapCharArray(JNIEnv *env, const cv::Mat &image) { } extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_Yolact_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { +Java_wificar_Yolact_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { if (Yolact::detector != nullptr) { delete Yolact::detector; Yolact::detector = nullptr; @@ -284,10 +284,10 @@ Java_com_wzt_yolov5_Yolact_init(JNIEnv *env, jclass clazz, jobject assetManager, } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_Yolact_detect(JNIEnv *env, jclass clazz, jobject image) { +Java_wificar_Yolact_detect(JNIEnv *env, jclass clazz, jobject image) { auto result = Yolact::detector->detect_yolact(env, image); - auto yolact_mask = env->FindClass("com/wzt/yolov5/YolactMask"); + auto yolact_mask = env->FindClass("wificar/YolactMask"); // auto cid = env->GetMethodID(yolact_mask, "", "(FFFFIF[F[I)V"); auto cid = env->GetMethodID(yolact_mask, "", "(FFFFIF[F[C)V"); jobjectArray ret = env->NewObjectArray(result.size(), yolact_mask, nullptr); @@ -357,7 +357,7 @@ std::string jstring2str(JNIEnv *env, jstring jstr) { } extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_ocr_ChineseOCRLite_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { +Java_wificar_ocr_ChineseOCRLite_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { if (OCR::detector != nullptr) { delete OCR::detector; OCR::detector = nullptr; @@ -369,13 +369,13 @@ Java_com_wzt_yolov5_ocr_ChineseOCRLite_init(JNIEnv *env, jclass clazz, jobject a } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_ocr_ChineseOCRLite_detect(JNIEnv *env, jclass clazz, jobject bitmap, jint short_size) { +Java_wificar_ocr_ChineseOCRLite_detect(JNIEnv *env, jclass clazz, jobject bitmap, jint short_size) { auto ocrResult = OCR::detector->detect(env, bitmap, short_size); // LOGD("jni ocr result size:%ld", ocrResult.size()); // LOGD("jni ocr ocrresult[0].pre_res size:%ld", ocrResult[0].pre_res.size()); // LOGD("jni ocr ocrresult[0][0]:%s", ocrResult[0].pre_res[0].c_str()); - auto ocr_result = env->FindClass("com/wzt/yolov5/ocr/OCRResult"); + auto ocr_result = env->FindClass("wificar/ocr/OCRResult"); auto cid = env->GetMethodID(ocr_result, "", "([D[DLjava/lang/String;)V"); jobjectArray ret = env->NewObjectArray(ocrResult.size(), ocr_result, nullptr); int i = 0; @@ -422,7 +422,7 @@ Java_com_wzt_yolov5_ocr_ChineseOCRLite_detect(JNIEnv *env, jclass clazz, jobject ENet ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_ENet_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { +Java_wificar_ENet_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { if (ENet::detector != nullptr) { delete ENet::detector; ENet::detector = nullptr; @@ -434,7 +434,7 @@ Java_com_wzt_yolov5_ENet_init(JNIEnv *env, jclass, jobject assetManager, jboolea } extern "C" JNIEXPORT jfloatArray JNICALL -Java_com_wzt_yolov5_ENet_detect(JNIEnv *env, jclass, jobject image) { +Java_wificar_ENet_detect(JNIEnv *env, jclass, jobject image) { auto result = ENet::detector->detect_enet(env, image); int output_w = result.w; @@ -459,7 +459,7 @@ Java_com_wzt_yolov5_ENet_detect(JNIEnv *env, jclass, jobject image) { MobileNetv3_Seg ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_MbnSeg_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { +Java_wificar_MbnSeg_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { if (MBNV3Seg::detector != nullptr) { delete MBNV3Seg::detector; MBNV3Seg::detector = nullptr; @@ -471,7 +471,7 @@ Java_com_wzt_yolov5_MbnSeg_init(JNIEnv *env, jclass, jobject assetManager, jbool } extern "C" JNIEXPORT jfloatArray JNICALL -Java_com_wzt_yolov5_MbnSeg_detect(JNIEnv *env, jclass, jobject image) { +Java_wificar_MbnSeg_detect(JNIEnv *env, jclass, jobject image) { auto result = MBNV3Seg::detector->detect_mbnseg(env, image); int output_w = result.w; @@ -496,7 +496,7 @@ Java_com_wzt_yolov5_MbnSeg_detect(JNIEnv *env, jclass, jobject image) { MobileNetv2_FCN ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_MbnFCN_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { +Java_wificar_MbnFCN_init(JNIEnv *env, jclass, jobject assetManager, jboolean useGPU) { if (MbnFCN::detector != nullptr) { delete MbnFCN::detector; MbnFCN::detector = nullptr; @@ -508,7 +508,7 @@ Java_com_wzt_yolov5_MbnFCN_init(JNIEnv *env, jclass, jobject assetManager, jbool } extern "C" JNIEXPORT jfloatArray JNICALL -Java_com_wzt_yolov5_MbnFCN_detect(JNIEnv *env, jclass, jobject image) { +Java_wificar_MbnFCN_detect(JNIEnv *env, jclass, jobject image) { auto result = MbnFCN::detector->detect_mbnfcn(env, image); int output_w = result.w; @@ -534,7 +534,7 @@ Java_com_wzt_yolov5_MbnFCN_detect(JNIEnv *env, jclass, jobject image) { ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_FaceLandmark_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { +Java_wificar_FaceLandmark_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { if (FaceLandmark::detector != nullptr) { delete FaceLandmark::detector; FaceLandmark::detector = nullptr; @@ -546,10 +546,10 @@ Java_com_wzt_yolov5_FaceLandmark_init(JNIEnv *env, jclass clazz, jobject assetMa } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_FaceLandmark_detect(JNIEnv *env, jclass clazz, jobject image) { +Java_wificar_FaceLandmark_detect(JNIEnv *env, jclass clazz, jobject image) { auto result = FaceLandmark::detector->detect(env, image); - auto box_cls = env->FindClass("com/wzt/yolov5/FaceKeyPoint"); + auto box_cls = env->FindClass("wificar/FaceKeyPoint"); auto cid = env->GetMethodID(box_cls, "", "(FF)V"); jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); int i = 0; @@ -567,7 +567,7 @@ Java_com_wzt_yolov5_FaceLandmark_detect(JNIEnv *env, jclass clazz, jobject image DBFace ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_DBFace_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { +Java_wificar_DBFace_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { if (DBFace::detector != nullptr) { delete DBFace::detector; DBFace::detector = nullptr; @@ -579,11 +579,11 @@ Java_com_wzt_yolov5_DBFace_init(JNIEnv *env, jclass clazz, jobject assetManager, } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_DBFace_detect(JNIEnv *env, jclass clazz, jobject image, jdouble threshold, jdouble nms_threshold) { +Java_wificar_DBFace_detect(JNIEnv *env, jclass clazz, jobject image, jdouble threshold, jdouble nms_threshold) { auto result = DBFace::detector->detect(env, image, threshold, nms_threshold); // LOGD("jni dbface size:%d %f %f", result.size(), threshold, nms_threshold); - auto box_cls = env->FindClass("com/wzt/yolov5/KeyPoint"); + auto box_cls = env->FindClass("wificar/KeyPoint"); auto cid = env->GetMethodID(box_cls, "", "([F[FFFFFF)V"); jobjectArray ret = env->NewObjectArray(result.size(), box_cls, nullptr); int i = 0; @@ -616,7 +616,7 @@ Java_com_wzt_yolov5_DBFace_detect(JNIEnv *env, jclass clazz, jobject image, jdou ********************************************************************************************/ extern "C" JNIEXPORT void JNICALL -Java_com_wzt_yolov5_LightOpenPose_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { +Java_wificar_LightOpenPose_init(JNIEnv *env, jclass clazz, jobject assetManager, jboolean useGPU) { if (LightOpenPose::detector != nullptr) { delete LightOpenPose::detector; LightOpenPose::detector = nullptr; @@ -628,10 +628,10 @@ Java_com_wzt_yolov5_LightOpenPose_init(JNIEnv *env, jclass clazz, jobject assetM } extern "C" JNIEXPORT jobjectArray JNICALL -Java_com_wzt_yolov5_LightOpenPose_detect(JNIEnv *env, jclass clazz, jobject image) { +Java_wificar_LightOpenPose_detect(JNIEnv *env, jclass clazz, jobject image) { auto poses = LightOpenPose::detector->detect(env, image); - auto box_cls = env->FindClass("com/wzt/yolov5/OpenPoseKeyPoint"); + auto box_cls = env->FindClass("wificar/OpenPoseKeyPoint"); auto cid = env->GetMethodID(box_cls, "", "([F[FF)V"); jobjectArray ret = env->NewObjectArray(poses.size(), box_cls, nullptr); int i = 0; diff --git a/src/app/src/main/java/wificar/Box.java b/src/app/src/main/java/wificar/Box.java new file mode 100644 index 0000000..8a1aaf3 --- /dev/null +++ b/src/app/src/main/java/wificar/Box.java @@ -0,0 +1,46 @@ +package wificar; + +import android.graphics.Color; +import android.graphics.RectF; + +import java.util.Random; + +public class Box { + public float x0,y0,x1,y1; + private int label; + private float score; + private static String[] labels={"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", + "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", + "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", + "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", + "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", + "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", + "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", + "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", + "hair drier", "toothbrush"}; + public Box(float x0,float y0, float x1, float y1, int label, float score){ + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; + this.label = label; + this.score = score; + } + + public RectF getRect(){ + return new RectF(x0,y0,x1,y1); + } + + public String getLabel(){ + return labels[label]; + } + + public float getScore(){ + return score; + } + + public int getColor(){ + Random random = new Random(label); + return Color.argb(255,random.nextInt(256),random.nextInt(256),random.nextInt(256)); + } +} diff --git a/src/app/src/main/java/wificar/KeyPoint.java b/src/app/src/main/java/wificar/KeyPoint.java new file mode 100644 index 0000000..74c59eb --- /dev/null +++ b/src/app/src/main/java/wificar/KeyPoint.java @@ -0,0 +1,75 @@ +package wificar; + + +public class KeyPoint { + public float[] x; + public float[] y; + public float x0, y0, x1, y1; + public float score; + + public KeyPoint(float[] x, float[] y, float x0, float y0, float x1, float y1, float score) { + this.x = x; + this.y = y; + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; + this.score = score; + } + + public float[] getX() { + return x; + } + + public void setX(float[] x) { + this.x = x; + } + + public float[] getY() { + return y; + } + + public void setY(float[] y) { + this.y = y; + } + + public float getX0() { + return x0; + } + + public void setX0(float x0) { + this.x0 = x0; + } + + public float getY0() { + return y0; + } + + public void setY0(float y0) { + this.y0 = y0; + } + + 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 getScore() { + return score; + } + + public void setScore(float score) { + this.score = score; + } +} diff --git a/src/app/src/main/java/wificar/MyMainFrm.java b/src/app/src/main/java/wificar/MyMainFrm.java index b204225..01742cc 100644 --- a/src/app/src/main/java/wificar/MyMainFrm.java +++ b/src/app/src/main/java/wificar/MyMainFrm.java @@ -7,6 +7,10 @@ package wificar; import android.app.Activity; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; @@ -16,6 +20,8 @@ import android.widget.Button; import android.widget.EditText; import android.widget.Toast; +import java.util.Random; + import my.wificar.R; public class MyMainFrm extends Activity { @@ -44,6 +50,8 @@ public class MyMainFrm extends Activity { * Button_go 启动按钮 * * */ + YOLOv5.init(getAssets(), true); + SimplePose.init(getAssets(),true); setContentView(R.layout.mymainfrm); @@ -114,8 +122,6 @@ public class MyMainFrm extends Activity { } return super.onKeyDown(keyCode, event); } - - } diff --git a/src/app/src/main/java/wificar/MySurfaceView.java b/src/app/src/main/java/wificar/MySurfaceView.java index d8d3461..231032c 100644 --- a/src/app/src/main/java/wificar/MySurfaceView.java +++ b/src/app/src/main/java/wificar/MySurfaceView.java @@ -5,23 +5,41 @@ package wificar; * 如发现侵权行为,小R科技将择机通过法律途径予以起诉! * */ +import android.Manifest; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; 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.Rect; +import android.graphics.YuvImage; +import android.net.Uri; +import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; +import android.util.Size; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; +import android.widget.ImageView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import androidx.lifecycle.LifecycleOwner; + import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -29,6 +47,14 @@ import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.ByteBuffer; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; + +import my.wificar.R; +import wseemann.media.FFmpegMediaMetadataRetriever; public class MySurfaceView extends SurfaceView implements Callback { private static int mScreenWidth; @@ -45,8 +71,12 @@ public class MySurfaceView extends SurfaceView implements Callback { private Bitmap mBitmap; private boolean isThreadRunning = true; + private MyVideo activity; + private ImageView floatingView; + public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); + activity = (MyVideo) context; Constant.context = context; initialize(); p = new Paint(); @@ -71,7 +101,7 @@ public class MySurfaceView extends SurfaceView implements Callback { } }; - + SimplePose.init(context.getAssets(), USE_GPU); } private void initialize() { @@ -346,6 +376,8 @@ public class MySurfaceView extends SurfaceView implements Callback { width, height, false); + //TODO 获取到 bitmap 了 + detectOnModel(mBitmap); canvas.drawBitmap( mBitmap, (mScreenWidth - width) / 2, @@ -377,4 +409,130 @@ public class MySurfaceView extends SurfaceView implements Callback { } } + public static int YOLOV5S = 1; + public static int YOLOV4_TINY = 2; + public static int MOBILENETV2_YOLOV3_NANO = 3; + public static int SIMPLE_POSE = 4; + public static int YOLACT = 5; + public static int ENET = 6; + public static int FACE_LANDMARK = 7; + public static int DBFACE = 8; + public static int MOBILENETV2_FCN = 9; + public static int MOBILENETV3_SEG = 10; + public static int YOLOV5_CUSTOM_LAYER = 11; + public static int NANODET = 12; + public static int YOLO_FASTEST_XL = 13; + public static int LIGHT_OPEN_POSE = 14; + + public static final int USE_MODEL = SIMPLE_POSE; + public static boolean USE_GPU = false; + + private static final int REQUEST_CAMERA = 1; + private static final int REQUEST_PICK_IMAGE = 2; + private static final int REQUEST_PICK_VIDEO = 3; + private static String[] PERMISSIONS_CAMERA = { + Manifest.permission.CAMERA + }; + private double threshold = 0.3, nms_threshold = 0.7; + + protected float videoSpeed = 1.0f; + protected long videoCurFrameLoc = 0; + private AtomicBoolean detectCamera = new AtomicBoolean(false); + private AtomicBoolean detectPhoto = new AtomicBoolean(false); + private AtomicBoolean detectVideo = new AtomicBoolean(false); + + private long startTime = 0; + private long endTime = 0; + private int width; + private int height; + + double total_fps = 0; + int fps_count = 0; + + protected Bitmap mutableBitmap; + + ExecutorService detectService = Executors.newSingleThreadExecutor(); + + FFmpegMediaMetadataRetriever mmr; + + private static boolean useCamera = true; + + private void detectOnModel(Bitmap image) { + startTime = System.currentTimeMillis(); + detectService.execute(() -> { + detectAndDraw(image); + showResultOnUI(); + }); + } + + protected void showResultOnUI() { + if(floatingView == null) { + floatingView = activity.findViewById(R.id.floatingView); + } + activity.runOnUiThread(() -> { + if(mutableBitmap == null)return; + floatingView.setImageBitmap(mutableBitmap); + }); + } + protected Bitmap drawPersonPose(Bitmap mutableBitmap, KeyPoint[] keyPoints) { + if (keyPoints == null || keyPoints.length <= 0) { + return mutableBitmap; + } + int[][] joint_pairs = {{0, 1}, {1, 3}, {0, 2}, {2, 4}, {5, 6}, {5, 7}, {7, 9}, {6, 8}, {8, 10}, {5, 11}, {6, 12}, {11, 12}, {11, 13}, {12, 14}, {13, 15}, {14, 16}}; + Canvas canvas = new Canvas(mutableBitmap); + final Paint keyPointPaint = new Paint(); + keyPointPaint.setAlpha(200); + keyPointPaint.setStyle(Paint.Style.STROKE); + keyPointPaint.setColor(Color.BLUE); + int color = Color.BLUE; + // 画线、画框、画点 + for (int i = 0; i < keyPoints.length; i++) { + // 其它随机颜色 + Random random = new Random(i + 2020); + color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256)); + // 画线 + keyPointPaint.setStrokeWidth(5 * mutableBitmap.getWidth() / 800.0f); + for (int j = 0; j < 16; j++) { + int pl0 = joint_pairs[j][0]; + int pl1 = joint_pairs[j][1]; + if ((pl0 % 2 == 1) && (pl1 % 2 == 1) && pl0 >= 5 && pl1 >= 5) { + keyPointPaint.setColor(Color.RED); + } else { + keyPointPaint.setColor(color); + } + canvas.drawLine(keyPoints[i].x[joint_pairs[j][0]], keyPoints[i].y[joint_pairs[j][0]], + keyPoints[i].x[joint_pairs[j][1]], keyPoints[i].y[joint_pairs[j][1]], + keyPointPaint); + } + // 画点 + keyPointPaint.setColor(Color.GREEN); + keyPointPaint.setStrokeWidth(8 * mutableBitmap.getWidth() / 800.0f); + for (int n = 0; n < 17; n++) { + canvas.drawPoint(keyPoints[i].x[n], keyPoints[i].y[n], keyPointPaint); + } + // 画框 + keyPointPaint.setColor(color); + keyPointPaint.setStrokeWidth(3 * mutableBitmap.getWidth() / 800.0f); + canvas.drawRect(keyPoints[i].x0, keyPoints[i].y0, keyPoints[i].x1, keyPoints[i].y1, keyPointPaint); + } + return mutableBitmap; + } + + protected Bitmap detectAndDraw(Bitmap image) { + Box[] result = null; + KeyPoint[] keyPoints = null; + if (USE_MODEL == YOLOV5S) { + result = YOLOv5.detect(image, threshold, nms_threshold); + } else if (USE_MODEL == SIMPLE_POSE) { + keyPoints = SimplePose.detect(image); + } + if (result == null && keyPoints == null) { + detectCamera.set(false); + return image; + } + if (USE_MODEL == SIMPLE_POSE) { + mutableBitmap = drawPersonPose(image, keyPoints); + } + return mutableBitmap; + } } \ No newline at end of file diff --git a/src/app/src/main/java/wificar/MyVideo.java b/src/app/src/main/java/wificar/MyVideo.java index 4c081ab..209d2ae 100644 --- a/src/app/src/main/java/wificar/MyVideo.java +++ b/src/app/src/main/java/wificar/MyVideo.java @@ -60,10 +60,6 @@ public class MyVideo extends Activity { BtnRight = findViewById(R.id.button_right); BtnStop = findViewById(R.id.button_stop); - rockerView = new RockerView(this,socketWriter,this.getApplicationContext(),null); - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(600,600); - addContentView(rockerView,params); - Intent intent = getIntent(); //从Intent当中根据key取得value CameraIp = intent.getStringExtra("CameraIp"); @@ -73,6 +69,9 @@ public class MyVideo extends Activity { Log.d("wifirobot", "CtrlPort is :++++" + CtrlPort); r.GetCameraIP(CameraIp); InitSocket(); + rockerView = new RockerView(this,socketWriter,this.getApplicationContext(),null); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(600,600); + addContentView(rockerView,params); BtnForward.setOnClickListener(arg0 -> { // TODO Auto-generated method stub try { diff --git a/src/app/src/main/java/wificar/SimplePose.java b/src/app/src/main/java/wificar/SimplePose.java new file mode 100644 index 0000000..64e2e1d --- /dev/null +++ b/src/app/src/main/java/wificar/SimplePose.java @@ -0,0 +1,13 @@ +package wificar; + +import android.content.res.AssetManager; +import android.graphics.Bitmap; + +public class SimplePose { + static { + System.loadLibrary("yolov5"); + } + + public static native void init(AssetManager manager, boolean useGPU); + public static native KeyPoint[] detect(Bitmap bitmap); +} diff --git a/src/app/src/main/java/wificar/YOLOv5.java b/src/app/src/main/java/wificar/YOLOv5.java new file mode 100644 index 0000000..fc3a75c --- /dev/null +++ b/src/app/src/main/java/wificar/YOLOv5.java @@ -0,0 +1,16 @@ +package wificar; + +import android.content.res.AssetManager; +import android.graphics.Bitmap; + +public class YOLOv5 { + static { + System.loadLibrary("yolov5"); + } + + public static native void init(AssetManager manager, boolean useGPU); + public static native Box[] detect(Bitmap bitmap, double threshold, double nms_threshold); + + public static native void initCustomLayer(AssetManager manager, boolean useGPU); + public static native Box[] detectCustomLayer(Bitmap bitmap, double threshold, double nms_threshold); +} diff --git a/src/app/src/main/res/layout/myvideo.xml b/src/app/src/main/res/layout/myvideo.xml index 26449bf..cdc18eb 100644 --- a/src/app/src/main/res/layout/myvideo.xml +++ b/src/app/src/main/res/layout/myvideo.xml @@ -18,6 +18,10 @@ android:id="@+id/mySurfaceViewVideo" android:layout_width="match_parent" android:layout_height="match_parent" /> +