正在显示
3 个修改的文件
包含
123 行增加
和
7 行删除
| @@ -55,7 +55,16 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { | @@ -55,7 +55,16 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { | ||
| 55 | ), | 55 | ), |
| 56 | ) | 56 | ) |
| 57 | 57 | ||
| 58 | - private val processor = OpencvVideoProcessor() | 58 | + private val processor = OpencvVideoProcessor().apply { |
| 59 | + // Load model before processing to avoid unsupported overlay | ||
| 60 | + // modelId: 0=mobilenetv3, sizeId: 6=640, intraInter:1, postproc:0(fast), cpuGpu:0(CPU) | ||
| 61 | + try { | ||
| 62 | + val ok = loadModel(application.assets, 0, 0, 1, 0, 0) | ||
| 63 | + android.util.Log.d("MainViewModel", "OpencvVideoProcessor.loadModel result=$ok") | ||
| 64 | + } catch (t: Throwable) { | ||
| 65 | + android.util.Log.e("MainViewModel", "loadModel failed", t) | ||
| 66 | + } | ||
| 67 | + } | ||
| 59 | 68 | ||
| 60 | private var cameraProvider: CameraCapturerUtils.CameraProvider? = null | 69 | private var cameraProvider: CameraCapturerUtils.CameraProvider? = null |
| 61 | 70 |
| @@ -38,6 +38,9 @@ public class OpencvVideoProcessor extends NoDropVideoProcessor { | @@ -38,6 +38,9 @@ public class OpencvVideoProcessor extends NoDropVideoProcessor { | ||
| 38 | } | 38 | } |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | + // Load model before processing to avoid unsupported overlay | ||
| 42 | + public native boolean loadModel(android.content.res.AssetManager mgr, int modelId, int sizeId, int intraInterId, int postprocId, int cpuGpu); | ||
| 43 | + | ||
| 41 | // Core native that processes I420 in/out fully in cpp | 44 | // Core native that processes I420 in/out fully in cpp |
| 42 | private static native boolean processI420ToI420( | 45 | private static native boolean processI420ToI420( |
| 43 | ByteBuffer y, int yStride, | 46 | ByteBuffer y, int yStride, |
| @@ -287,6 +287,93 @@ JNIEXPORT jboolean JNICALL Java_io_livekit_android_track_processing_video_RVMNcn | @@ -287,6 +287,93 @@ JNIEXPORT jboolean JNICALL Java_io_livekit_android_track_processing_video_RVMNcn | ||
| 287 | return JNI_TRUE; | 287 | return JNI_TRUE; |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | +// duplicate loadModel for OpencvVideoProcessor | ||
| 291 | +JNIEXPORT jboolean JNICALL Java_io_livekit_android_track_processing_video_OpencvVideoProcessor_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint sizeid, jint intrainterid, jint postprocid, jint cpugpu) | ||
| 292 | +{ | ||
| 293 | + if (modelid < 0 || modelid > 1 || sizeid < 0 || sizeid > 6 || intrainterid < 0 || intrainterid > 1 || postprocid < 0 || postprocid > 2 || cpugpu < 0 || cpugpu > 2) | ||
| 294 | + { | ||
| 295 | + return JNI_FALSE; | ||
| 296 | + } | ||
| 297 | + | ||
| 298 | + AAssetManager* mgr = AAssetManager_fromJava(env, assetManager); | ||
| 299 | + | ||
| 300 | + __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "loadModel %p (OpencvVideoProcessor)", mgr); | ||
| 301 | + | ||
| 302 | + const char* modeltypes[2] = | ||
| 303 | + { | ||
| 304 | + "mobilenetv3", | ||
| 305 | + "resnet50" | ||
| 306 | + }; | ||
| 307 | + | ||
| 308 | + const int sizetypes[7] = | ||
| 309 | + { | ||
| 310 | + 256, | ||
| 311 | + 320, | ||
| 312 | + 384, | ||
| 313 | + 448, | ||
| 314 | + 512, | ||
| 315 | + 576, | ||
| 316 | + 640 | ||
| 317 | + }; | ||
| 318 | + | ||
| 319 | + std::string parampath = std::string("rvm_") + modeltypes[(int)modelid] + ".ncnn.param"; | ||
| 320 | + std::string modelpath = std::string("rvm_") + modeltypes[(int)modelid] + ".ncnn.bin"; | ||
| 321 | + bool use_gpu = (int)cpugpu == 1; | ||
| 322 | + bool use_turnip = (int)cpugpu == 2; | ||
| 323 | + | ||
| 324 | + { | ||
| 325 | + ncnn::MutexLockGuard g(lock); | ||
| 326 | + | ||
| 327 | + { | ||
| 328 | + // reset inter feats | ||
| 329 | + g_feats.r1.release(); | ||
| 330 | + g_feats.r2.release(); | ||
| 331 | + g_feats.r3.release(); | ||
| 332 | + g_feats.r4.release(); | ||
| 333 | + | ||
| 334 | + static int old_modelid = 0; | ||
| 335 | + static int old_cpugpu = 0; | ||
| 336 | + if (modelid != old_modelid || cpugpu != old_cpugpu) | ||
| 337 | + { | ||
| 338 | + delete g_rvm; | ||
| 339 | + g_rvm = 0; | ||
| 340 | + } | ||
| 341 | + old_modelid = modelid; | ||
| 342 | + old_cpugpu = cpugpu; | ||
| 343 | + | ||
| 344 | + ncnn::destroy_gpu_instance(); | ||
| 345 | + | ||
| 346 | + if (use_turnip) | ||
| 347 | + { | ||
| 348 | + ncnn::create_gpu_instance("libvulkan_freedreno.so"); | ||
| 349 | + } | ||
| 350 | + else if (use_gpu) | ||
| 351 | + { | ||
| 352 | + ncnn::create_gpu_instance(); | ||
| 353 | + } | ||
| 354 | + | ||
| 355 | + if (!g_rvm) | ||
| 356 | + { | ||
| 357 | + g_rvm = new RVM; | ||
| 358 | + | ||
| 359 | + g_rvm->load(mgr, parampath.c_str(), modelpath.c_str(), use_gpu || use_turnip); | ||
| 360 | + } | ||
| 361 | + g_rvm->set_model_type((int)modelid); | ||
| 362 | + g_rvm->set_target_size(sizetypes[(int)sizeid]); | ||
| 363 | + g_rvm->set_intra_inter((int)intrainterid); | ||
| 364 | + | ||
| 365 | + if (postprocid == 0) | ||
| 366 | + g_rvm->set_postproc_mode(false, true, false); | ||
| 367 | + if (postprocid == 1) | ||
| 368 | + g_rvm->set_postproc_mode(false, false, true); | ||
| 369 | + if (postprocid == 2) | ||
| 370 | + g_rvm->set_postproc_mode(true, false, false); | ||
| 371 | + } | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + return JNI_TRUE; | ||
| 375 | +} | ||
| 376 | + | ||
| 290 | // public native boolean openCamera(int facing); | 377 | // public native boolean openCamera(int facing); |
| 291 | JNIEXPORT jboolean JNICALL Java_io_livekit_android_track_processing_video_RVMNcnn_openCamera(JNIEnv* env, jobject thiz, jint facing) | 378 | JNIEXPORT jboolean JNICALL Java_io_livekit_android_track_processing_video_RVMNcnn_openCamera(JNIEnv* env, jobject thiz, jint facing) |
| 292 | { | 379 | { |
| @@ -498,24 +585,41 @@ JNIEXPORT jboolean JNICALL Java_io_livekit_android_track_processing_video_Opencv | @@ -498,24 +585,41 @@ JNIEXPORT jboolean JNICALL Java_io_livekit_android_track_processing_video_Opencv | ||
| 498 | 585 | ||
| 499 | // Wrap as a single-channel Mat (H + H/2) x W and convert to BGR | 586 | // Wrap as a single-channel Mat (H + H/2) x W and convert to BGR |
| 500 | cv::Mat i420_mat(height + height / 2, width, CV_8UC1, i420_in.data()); | 587 | cv::Mat i420_mat(height + height / 2, width, CV_8UC1, i420_in.data()); |
| 501 | - cv::Mat bgr; | ||
| 502 | - cv::cvtColor(i420_mat, bgr, cv::COLOR_YUV2BGR_I420); | 588 | + cv::Mat rgb; |
| 589 | + cv::cvtColor(i420_mat, rgb, cv::COLOR_YUV2RGB_I420); | ||
| 590 | + // Rotate to upright orientation for the model | ||
| 591 | + if (rotation == 90) { | ||
| 592 | + cv::rotate(rgb, rgb, cv::ROTATE_90_CLOCKWISE); | ||
| 593 | + } else if (rotation == 180) { | ||
| 594 | + cv::rotate(rgb, rgb, cv::ROTATE_180); | ||
| 595 | + } else if (rotation == 270) { | ||
| 596 | + cv::rotate(rgb, rgb, cv::ROTATE_90_COUNTERCLOCKWISE); | ||
| 597 | + } | ||
| 503 | 598 | ||
| 504 | // Process with RVM | 599 | // Process with RVM |
| 505 | { | 600 | { |
| 506 | ncnn::MutexLockGuard g(lock); | 601 | ncnn::MutexLockGuard g(lock); |
| 507 | if (g_rvm) { | 602 | if (g_rvm) { |
| 508 | cv::Mat fgr, pha, seg; | 603 | cv::Mat fgr, pha, seg; |
| 509 | - g_rvm->detect(bgr, g_feats, fgr, pha, seg); | ||
| 510 | - g_rvm->draw(bgr, fgr, pha, seg); | 604 | + g_rvm->detect(rgb, g_feats, fgr, pha, seg); |
| 605 | + g_rvm->draw(rgb, fgr, pha, seg); | ||
| 511 | } else { | 606 | } else { |
| 512 | - draw_unsupported(bgr); | 607 | + draw_unsupported(rgb); |
| 608 | + } | ||
| 513 | } | 609 | } |
| 610 | + | ||
| 611 | + // Rotate back to original orientation before returning to I420 | ||
| 612 | + if (rotation == 90) { | ||
| 613 | + cv::rotate(rgb, rgb, cv::ROTATE_90_COUNTERCLOCKWISE); | ||
| 614 | + } else if (rotation == 180) { | ||
| 615 | + cv::rotate(rgb, rgb, cv::ROTATE_180); | ||
| 616 | + } else if (rotation == 270) { | ||
| 617 | + cv::rotate(rgb, rgb, cv::ROTATE_90_CLOCKWISE); | ||
| 514 | } | 618 | } |
| 515 | 619 | ||
| 516 | // Convert back to I420 | 620 | // Convert back to I420 |
| 517 | cv::Mat i420_out; | 621 | cv::Mat i420_out; |
| 518 | - cv::cvtColor(bgr, i420_out, cv::COLOR_BGR2YUV_I420); | 622 | + cv::cvtColor(rgb, i420_out, cv::COLOR_RGB2YUV_I420); |
| 519 | if (i420_out.empty() || i420_out.cols != width || i420_out.rows != height + height / 2) | 623 | if (i420_out.empty() || i420_out.cols != width || i420_out.rows != height + height / 2) |
| 520 | return JNI_FALSE; | 624 | return JNI_FALSE; |
| 521 | 625 |
-
请 注册 或 登录 后发表评论