diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt index b1e937a..f717f82 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt @@ -9,4 +9,5 @@ var sceneName = "" var inspectionId = "" var mainDicModels: MutableList = ArrayList() + var sceneDicModels: MutableList = ArrayList() } \ No newline at end of file diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt index b1e937a..f717f82 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt @@ -9,4 +9,5 @@ var sceneName = "" var inspectionId = "" var mainDicModels: MutableList = ArrayList() + var sceneDicModels: MutableList = ArrayList() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt index 9b8eb2f..611b815 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityCheckManifestBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class CheckManifestActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_check_manifest_l, sceneModels + R.layout.item_check_manifest_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt index b1e937a..f717f82 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt @@ -9,4 +9,5 @@ var sceneName = "" var inspectionId = "" var mainDicModels: MutableList = ArrayList() + var sceneDicModels: MutableList = ArrayList() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt index 9b8eb2f..611b815 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityCheckManifestBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class CheckManifestActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_check_manifest_l, sceneModels + R.layout.item_check_manifest_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt index fb43a2b..71adcf5 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt @@ -30,6 +30,7 @@ import com.casic.br.ar.app.vm.InspectionViewModel import com.casic.br.ar.app.widgets.DetectResultDialog import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.isNumber import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.extensions.timestampToDate @@ -63,11 +64,10 @@ private lateinit var alarmViewModel: AlarmViewModel private lateinit var checkManifestViewModel: CheckManifestViewModel private var mainDicModels: MutableList = ArrayList() - private var sceneDicModels: MutableList = ArrayList() private var isDetectTarget = false private var alarmCode = "" private var checkItemCount = 0 - private var troubleCount = 0 + private var checkPassCount = 0 override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -110,15 +110,6 @@ } } - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneDicModels = it.data - } - } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] imageFileViewModel.resultModel.observe(this) { @@ -167,7 +158,7 @@ AlertControlDialog.Builder() .setContext(this) .setTitle("温馨提示") - .setMessage("所有检查均已完成,共${targetSet.size}项通过,存在${troubleCount}项隐患,是否结束检查?") + .setMessage("所有检查均已完成,共${checkPassCount}项通过,存在${checkItemCount - checkPassCount}项隐患,是否结束检查?") .setNegativeButton("取消") .setPositiveButton("结束检查") .setOnDialogButtonClickListener(object : @@ -224,7 +215,7 @@ override fun onSegmentation( segmentationOutput: ArrayList, detectOutput: ArrayList ) { - if (segmentationOutput.isEmpty() || detectOutput.isEmpty()) { + if (detectOutput.isEmpty()) { binding.detectView.updateTargetPosition() } else { val segmentationResults = ArrayList() @@ -239,13 +230,11 @@ binding.detectView.updateTargetPosition(segmentationResults, detectResults) - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - lifecycleScope.launch(Dispatchers.Main) { - binding.checkedCountView.text = "${targetSet.size}项" - binding.noCheckCountView.text = "${checkItemCount - targetSet.size}项" + lifecycleScope.launch(Dispatchers.Main) { + detectResults.forEach { + val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] + if (label.isInScene(RuntimeCache.sceneName)) { + targetSet.add(label) } } } @@ -414,13 +403,16 @@ } } - if (warnings == "") { - return + val target = if (warnings == "") { + detectResults.first().type.toString() + } else { + warnings } + //显示弹框 val message = weakReferenceHandler.obtainMessage() message.what = 2024082902 - message.obj = warnings + message.obj = target weakReferenceHandler.sendMessage(message) } } @@ -473,18 +465,18 @@ binding.sceneNameView.text = scene //获取检查清单数目 - for (dic in sceneDicModels) { + for (dic in RuntimeCache.sceneDicModels) { if (dic.name == scene) { checkManifestViewModel.getCheckManifestByScene( context, dic.value ) + + isDetectTarget = true + //调用多模型 + yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) return } } - - isDetectTarget = true - //调用多模型 - yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) } override fun onCancelClick() { @@ -494,17 +486,24 @@ } 2024082902 -> { - val target = msg.obj as String - if (detectedTargetSet.contains(target)) { - "该目标/隐患已识别过".show(this) - return true - } - //弹框 if (detectResultDialog.isShowing) { return true } + val target = msg.obj as String + if (target.isNumber()) { + if (detectedTargetSet.contains(target)) { + "${LocaleConstant.CLASS_NAMES_ARRAY[target.toInt()]}已识别过".show(this) + return true + } + } else { + if (detectedTargetSet.contains(target)) { + "该隐患已识别过".show(this) + return true + } + } + if (mat.width() > 0 || mat.height() > 0) { detectResultDialog.updateDialogContentView(target, mat, object : DetectResultDialog.OnDialogButtonClickListener { @@ -512,8 +511,14 @@ imageFileViewModel.uploadImage(file) detectedTargetSet.add(target) - troubleCount++ - binding.troubleCountView.text = "${troubleCount}项" + if (target.isNumber()) { + checkPassCount++ + binding.checkedCountView.text = "${checkPassCount}项" + binding.noCheckCountView.text = "${checkItemCount - checkPassCount}项" + if (checkItemCount - checkPassCount == 0) { + stopCheck() + } + } } }).show() } diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt index b1e937a..f717f82 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt @@ -9,4 +9,5 @@ var sceneName = "" var inspectionId = "" var mainDicModels: MutableList = ArrayList() + var sceneDicModels: MutableList = ArrayList() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt index 9b8eb2f..611b815 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityCheckManifestBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class CheckManifestActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_check_manifest_l, sceneModels + R.layout.item_check_manifest_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt index fb43a2b..71adcf5 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt @@ -30,6 +30,7 @@ import com.casic.br.ar.app.vm.InspectionViewModel import com.casic.br.ar.app.widgets.DetectResultDialog import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.isNumber import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.extensions.timestampToDate @@ -63,11 +64,10 @@ private lateinit var alarmViewModel: AlarmViewModel private lateinit var checkManifestViewModel: CheckManifestViewModel private var mainDicModels: MutableList = ArrayList() - private var sceneDicModels: MutableList = ArrayList() private var isDetectTarget = false private var alarmCode = "" private var checkItemCount = 0 - private var troubleCount = 0 + private var checkPassCount = 0 override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -110,15 +110,6 @@ } } - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneDicModels = it.data - } - } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] imageFileViewModel.resultModel.observe(this) { @@ -167,7 +158,7 @@ AlertControlDialog.Builder() .setContext(this) .setTitle("温馨提示") - .setMessage("所有检查均已完成,共${targetSet.size}项通过,存在${troubleCount}项隐患,是否结束检查?") + .setMessage("所有检查均已完成,共${checkPassCount}项通过,存在${checkItemCount - checkPassCount}项隐患,是否结束检查?") .setNegativeButton("取消") .setPositiveButton("结束检查") .setOnDialogButtonClickListener(object : @@ -224,7 +215,7 @@ override fun onSegmentation( segmentationOutput: ArrayList, detectOutput: ArrayList ) { - if (segmentationOutput.isEmpty() || detectOutput.isEmpty()) { + if (detectOutput.isEmpty()) { binding.detectView.updateTargetPosition() } else { val segmentationResults = ArrayList() @@ -239,13 +230,11 @@ binding.detectView.updateTargetPosition(segmentationResults, detectResults) - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - lifecycleScope.launch(Dispatchers.Main) { - binding.checkedCountView.text = "${targetSet.size}项" - binding.noCheckCountView.text = "${checkItemCount - targetSet.size}项" + lifecycleScope.launch(Dispatchers.Main) { + detectResults.forEach { + val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] + if (label.isInScene(RuntimeCache.sceneName)) { + targetSet.add(label) } } } @@ -414,13 +403,16 @@ } } - if (warnings == "") { - return + val target = if (warnings == "") { + detectResults.first().type.toString() + } else { + warnings } + //显示弹框 val message = weakReferenceHandler.obtainMessage() message.what = 2024082902 - message.obj = warnings + message.obj = target weakReferenceHandler.sendMessage(message) } } @@ -473,18 +465,18 @@ binding.sceneNameView.text = scene //获取检查清单数目 - for (dic in sceneDicModels) { + for (dic in RuntimeCache.sceneDicModels) { if (dic.name == scene) { checkManifestViewModel.getCheckManifestByScene( context, dic.value ) + + isDetectTarget = true + //调用多模型 + yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) return } } - - isDetectTarget = true - //调用多模型 - yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) } override fun onCancelClick() { @@ -494,17 +486,24 @@ } 2024082902 -> { - val target = msg.obj as String - if (detectedTargetSet.contains(target)) { - "该目标/隐患已识别过".show(this) - return true - } - //弹框 if (detectResultDialog.isShowing) { return true } + val target = msg.obj as String + if (target.isNumber()) { + if (detectedTargetSet.contains(target)) { + "${LocaleConstant.CLASS_NAMES_ARRAY[target.toInt()]}已识别过".show(this) + return true + } + } else { + if (detectedTargetSet.contains(target)) { + "该隐患已识别过".show(this) + return true + } + } + if (mat.width() > 0 || mat.height() > 0) { detectResultDialog.updateDialogContentView(target, mat, object : DetectResultDialog.OnDialogButtonClickListener { @@ -512,8 +511,14 @@ imageFileViewModel.uploadImage(file) detectedTargetSet.add(target) - troubleCount++ - binding.troubleCountView.text = "${troubleCount}项" + if (target.isNumber()) { + checkPassCount++ + binding.checkedCountView.text = "${checkPassCount}项" + binding.noCheckCountView.text = "${checkItemCount - checkPassCount}项" + if (checkItemCount - checkPassCount == 0) { + stopCheck() + } + } } }).show() } diff --git a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt index 97c9456..6a7faa8 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityHiddenTroubleBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class HiddenTroubleActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_hidden_trouble_l, sceneModels + R.layout.item_hidden_trouble_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt index b1e937a..f717f82 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt @@ -9,4 +9,5 @@ var sceneName = "" var inspectionId = "" var mainDicModels: MutableList = ArrayList() + var sceneDicModels: MutableList = ArrayList() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt index 9b8eb2f..611b815 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityCheckManifestBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class CheckManifestActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_check_manifest_l, sceneModels + R.layout.item_check_manifest_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt index fb43a2b..71adcf5 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt @@ -30,6 +30,7 @@ import com.casic.br.ar.app.vm.InspectionViewModel import com.casic.br.ar.app.widgets.DetectResultDialog import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.isNumber import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.extensions.timestampToDate @@ -63,11 +64,10 @@ private lateinit var alarmViewModel: AlarmViewModel private lateinit var checkManifestViewModel: CheckManifestViewModel private var mainDicModels: MutableList = ArrayList() - private var sceneDicModels: MutableList = ArrayList() private var isDetectTarget = false private var alarmCode = "" private var checkItemCount = 0 - private var troubleCount = 0 + private var checkPassCount = 0 override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -110,15 +110,6 @@ } } - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneDicModels = it.data - } - } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] imageFileViewModel.resultModel.observe(this) { @@ -167,7 +158,7 @@ AlertControlDialog.Builder() .setContext(this) .setTitle("温馨提示") - .setMessage("所有检查均已完成,共${targetSet.size}项通过,存在${troubleCount}项隐患,是否结束检查?") + .setMessage("所有检查均已完成,共${checkPassCount}项通过,存在${checkItemCount - checkPassCount}项隐患,是否结束检查?") .setNegativeButton("取消") .setPositiveButton("结束检查") .setOnDialogButtonClickListener(object : @@ -224,7 +215,7 @@ override fun onSegmentation( segmentationOutput: ArrayList, detectOutput: ArrayList ) { - if (segmentationOutput.isEmpty() || detectOutput.isEmpty()) { + if (detectOutput.isEmpty()) { binding.detectView.updateTargetPosition() } else { val segmentationResults = ArrayList() @@ -239,13 +230,11 @@ binding.detectView.updateTargetPosition(segmentationResults, detectResults) - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - lifecycleScope.launch(Dispatchers.Main) { - binding.checkedCountView.text = "${targetSet.size}项" - binding.noCheckCountView.text = "${checkItemCount - targetSet.size}项" + lifecycleScope.launch(Dispatchers.Main) { + detectResults.forEach { + val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] + if (label.isInScene(RuntimeCache.sceneName)) { + targetSet.add(label) } } } @@ -414,13 +403,16 @@ } } - if (warnings == "") { - return + val target = if (warnings == "") { + detectResults.first().type.toString() + } else { + warnings } + //显示弹框 val message = weakReferenceHandler.obtainMessage() message.what = 2024082902 - message.obj = warnings + message.obj = target weakReferenceHandler.sendMessage(message) } } @@ -473,18 +465,18 @@ binding.sceneNameView.text = scene //获取检查清单数目 - for (dic in sceneDicModels) { + for (dic in RuntimeCache.sceneDicModels) { if (dic.name == scene) { checkManifestViewModel.getCheckManifestByScene( context, dic.value ) + + isDetectTarget = true + //调用多模型 + yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) return } } - - isDetectTarget = true - //调用多模型 - yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) } override fun onCancelClick() { @@ -494,17 +486,24 @@ } 2024082902 -> { - val target = msg.obj as String - if (detectedTargetSet.contains(target)) { - "该目标/隐患已识别过".show(this) - return true - } - //弹框 if (detectResultDialog.isShowing) { return true } + val target = msg.obj as String + if (target.isNumber()) { + if (detectedTargetSet.contains(target)) { + "${LocaleConstant.CLASS_NAMES_ARRAY[target.toInt()]}已识别过".show(this) + return true + } + } else { + if (detectedTargetSet.contains(target)) { + "该隐患已识别过".show(this) + return true + } + } + if (mat.width() > 0 || mat.height() > 0) { detectResultDialog.updateDialogContentView(target, mat, object : DetectResultDialog.OnDialogButtonClickListener { @@ -512,8 +511,14 @@ imageFileViewModel.uploadImage(file) detectedTargetSet.add(target) - troubleCount++ - binding.troubleCountView.text = "${troubleCount}项" + if (target.isNumber()) { + checkPassCount++ + binding.checkedCountView.text = "${checkPassCount}项" + binding.noCheckCountView.text = "${checkItemCount - checkPassCount}项" + if (checkItemCount - checkPassCount == 0) { + stopCheck() + } + } } }).show() } diff --git a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt index 97c9456..6a7faa8 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityHiddenTroubleBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class HiddenTroubleActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_hidden_trouble_l, sceneModels + R.layout.item_hidden_trouble_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt index 87e9b3b..8e4849f 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt @@ -6,9 +6,7 @@ import androidx.lifecycle.ViewModelProvider import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityLibraryBinding -import com.casic.br.ar.app.model.DictionaryModel import com.casic.br.ar.app.model.LibraryModel -import com.casic.br.ar.app.vm.ConfigViewModel import com.casic.br.ar.app.vm.LibraryViewModel import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder @@ -17,7 +15,6 @@ import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.LoadingDialogHub @@ -26,8 +23,6 @@ private val context = this private val marginOffset by lazy { 15.dp2px(this) } private lateinit var libraryViewModel: LibraryViewModel - private lateinit var configViewModel: ConfigViewModel - private var sceneModels: MutableList = ArrayList() override fun initEvent() { @@ -66,7 +61,7 @@ else -> 0 } - viewHolder.setImageResource(R.id.imageView,imageSource) + viewHolder.setImageResource(R.id.imageView, imageSource) .setText(R.id.textView, item.name) viewHolder.getView(R.id.itemRootView) @@ -88,8 +83,8 @@ override fun onItemClicked(position: Int, t: LibraryModel.DataModel) { when (position) { 0 -> navigatePageTo() - 1 -> navigatePageTo(sceneModels.toJson()) - 2 -> navigatePageTo(sceneModels.toJson()) + 1 -> navigatePageTo() + 2 -> navigatePageTo() 3 -> navigatePageTo(t.id) else -> "未实现".show(context) } @@ -97,14 +92,6 @@ }) } } - - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneModels = it.data - } - } } override fun initViewBinding(): ActivityLibraryBinding { diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt index b1e937a..f717f82 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt @@ -9,4 +9,5 @@ var sceneName = "" var inspectionId = "" var mainDicModels: MutableList = ArrayList() + var sceneDicModels: MutableList = ArrayList() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt index 9b8eb2f..611b815 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityCheckManifestBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class CheckManifestActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_check_manifest_l, sceneModels + R.layout.item_check_manifest_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt index fb43a2b..71adcf5 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt @@ -30,6 +30,7 @@ import com.casic.br.ar.app.vm.InspectionViewModel import com.casic.br.ar.app.widgets.DetectResultDialog import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.isNumber import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.extensions.timestampToDate @@ -63,11 +64,10 @@ private lateinit var alarmViewModel: AlarmViewModel private lateinit var checkManifestViewModel: CheckManifestViewModel private var mainDicModels: MutableList = ArrayList() - private var sceneDicModels: MutableList = ArrayList() private var isDetectTarget = false private var alarmCode = "" private var checkItemCount = 0 - private var troubleCount = 0 + private var checkPassCount = 0 override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -110,15 +110,6 @@ } } - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneDicModels = it.data - } - } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] imageFileViewModel.resultModel.observe(this) { @@ -167,7 +158,7 @@ AlertControlDialog.Builder() .setContext(this) .setTitle("温馨提示") - .setMessage("所有检查均已完成,共${targetSet.size}项通过,存在${troubleCount}项隐患,是否结束检查?") + .setMessage("所有检查均已完成,共${checkPassCount}项通过,存在${checkItemCount - checkPassCount}项隐患,是否结束检查?") .setNegativeButton("取消") .setPositiveButton("结束检查") .setOnDialogButtonClickListener(object : @@ -224,7 +215,7 @@ override fun onSegmentation( segmentationOutput: ArrayList, detectOutput: ArrayList ) { - if (segmentationOutput.isEmpty() || detectOutput.isEmpty()) { + if (detectOutput.isEmpty()) { binding.detectView.updateTargetPosition() } else { val segmentationResults = ArrayList() @@ -239,13 +230,11 @@ binding.detectView.updateTargetPosition(segmentationResults, detectResults) - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - lifecycleScope.launch(Dispatchers.Main) { - binding.checkedCountView.text = "${targetSet.size}项" - binding.noCheckCountView.text = "${checkItemCount - targetSet.size}项" + lifecycleScope.launch(Dispatchers.Main) { + detectResults.forEach { + val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] + if (label.isInScene(RuntimeCache.sceneName)) { + targetSet.add(label) } } } @@ -414,13 +403,16 @@ } } - if (warnings == "") { - return + val target = if (warnings == "") { + detectResults.first().type.toString() + } else { + warnings } + //显示弹框 val message = weakReferenceHandler.obtainMessage() message.what = 2024082902 - message.obj = warnings + message.obj = target weakReferenceHandler.sendMessage(message) } } @@ -473,18 +465,18 @@ binding.sceneNameView.text = scene //获取检查清单数目 - for (dic in sceneDicModels) { + for (dic in RuntimeCache.sceneDicModels) { if (dic.name == scene) { checkManifestViewModel.getCheckManifestByScene( context, dic.value ) + + isDetectTarget = true + //调用多模型 + yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) return } } - - isDetectTarget = true - //调用多模型 - yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) } override fun onCancelClick() { @@ -494,17 +486,24 @@ } 2024082902 -> { - val target = msg.obj as String - if (detectedTargetSet.contains(target)) { - "该目标/隐患已识别过".show(this) - return true - } - //弹框 if (detectResultDialog.isShowing) { return true } + val target = msg.obj as String + if (target.isNumber()) { + if (detectedTargetSet.contains(target)) { + "${LocaleConstant.CLASS_NAMES_ARRAY[target.toInt()]}已识别过".show(this) + return true + } + } else { + if (detectedTargetSet.contains(target)) { + "该隐患已识别过".show(this) + return true + } + } + if (mat.width() > 0 || mat.height() > 0) { detectResultDialog.updateDialogContentView(target, mat, object : DetectResultDialog.OnDialogButtonClickListener { @@ -512,8 +511,14 @@ imageFileViewModel.uploadImage(file) detectedTargetSet.add(target) - troubleCount++ - binding.troubleCountView.text = "${troubleCount}项" + if (target.isNumber()) { + checkPassCount++ + binding.checkedCountView.text = "${checkPassCount}项" + binding.noCheckCountView.text = "${checkItemCount - checkPassCount}项" + if (checkItemCount - checkPassCount == 0) { + stopCheck() + } + } } }).show() } diff --git a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt index 97c9456..6a7faa8 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityHiddenTroubleBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class HiddenTroubleActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_hidden_trouble_l, sceneModels + R.layout.item_hidden_trouble_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt index 87e9b3b..8e4849f 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt @@ -6,9 +6,7 @@ import androidx.lifecycle.ViewModelProvider import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityLibraryBinding -import com.casic.br.ar.app.model.DictionaryModel import com.casic.br.ar.app.model.LibraryModel -import com.casic.br.ar.app.vm.ConfigViewModel import com.casic.br.ar.app.vm.LibraryViewModel import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder @@ -17,7 +15,6 @@ import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.LoadingDialogHub @@ -26,8 +23,6 @@ private val context = this private val marginOffset by lazy { 15.dp2px(this) } private lateinit var libraryViewModel: LibraryViewModel - private lateinit var configViewModel: ConfigViewModel - private var sceneModels: MutableList = ArrayList() override fun initEvent() { @@ -66,7 +61,7 @@ else -> 0 } - viewHolder.setImageResource(R.id.imageView,imageSource) + viewHolder.setImageResource(R.id.imageView, imageSource) .setText(R.id.textView, item.name) viewHolder.getView(R.id.itemRootView) @@ -88,8 +83,8 @@ override fun onItemClicked(position: Int, t: LibraryModel.DataModel) { when (position) { 0 -> navigatePageTo() - 1 -> navigatePageTo(sceneModels.toJson()) - 2 -> navigatePageTo(sceneModels.toJson()) + 1 -> navigatePageTo() + 2 -> navigatePageTo() 3 -> navigatePageTo(t.id) else -> "未实现".show(context) } @@ -97,14 +92,6 @@ }) } } - - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneModels = it.data - } - } } override fun initViewBinding(): ActivityLibraryBinding { diff --git a/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt index 4bf9880..3adae0c 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt @@ -5,9 +5,12 @@ import android.view.View import android.widget.LinearLayout import android.widget.TextView +import androidx.lifecycle.ViewModelProvider import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityMainBinding import com.casic.br.ar.app.external.Yolov8ncnn +import com.casic.br.ar.app.utils.RuntimeCache +import com.casic.br.ar.app.vm.ConfigViewModel import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity @@ -21,6 +24,7 @@ private val kTag = "MainActivity" private val yolov8ncnn by lazy { Yolov8ncnn() } private val marginOffset by lazy { 25.dp2px(this) } + private lateinit var configViewModel: ConfigViewModel private lateinit var itemAdapter: NormalRecyclerAdapter override fun initEvent() { @@ -37,6 +41,15 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { + //获取到场景字典备用 + configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] + configViewModel.getDictionaryByCode(this, "securityScene") + configViewModel.dictionary.observe(this) { + if (it.code == 200) { + RuntimeCache.sceneDicModels = it.data + } + } + itemAdapter = object : NormalRecyclerAdapter( R.layout.item_main_rv_l, arrayListOf("开始检查", "检查记录", "知识库") ) { diff --git a/app/src/main/cpp/yolo.cpp b/app/src/main/cpp/yolo.cpp index 199b709..6cc45af 100644 --- a/app/src/main/cpp/yolo.cpp +++ b/app/src/main/cpp/yolo.cpp @@ -543,90 +543,87 @@ jobject segment_array_obj = env->NewObject(list_clazz, arraylist_init); jobject detect_array_obj = env->NewObject(list_clazz, arraylist_init); - //分割 + //AR眼镜性能低,不进行分割模型 { - ncnn::Extractor ex = yolo_s.create_extractor(); - ex.input("images", in_pad); - - ncnn::Mat out; - ex.extract("output", out); - - ncnn::Mat mask_proto; - ex.extract("seg", mask_proto); - - std::vector strides = {8, 16, 32}; - std::vector grid_strides; - generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); - - std::vector proposals; - std::vector objects8; - generate_proposals(grid_strides, out, prob_threshold, objects8, 6); - - proposals.insert(proposals.end(), objects8.begin(), objects8.end()); - - // sort all proposals by score from highest to lowest - qsort_descent_inplace(proposals); - - // apply nms with nms_threshold - std::vector picked; - nms_sorted_bboxes(proposals, picked, nms_threshold); - - int count = picked.size(); - - ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); - for (int i = 0; i < count; i++) { - float *mask_feat_ptr = mask_feat.row(i); - std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), - sizeof(float) * proposals[picked[i]].mask_feat.size()); - } - - ncnn::Mat mask_pred_result; - decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, - mask_pred_result); - - objects.resize(count); - for (int i = 0; i < count; i++) { - objects[i] = proposals[picked[i]]; - - // adjust offset to original unpadded - float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; - float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; - float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; - float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; - - // clip - x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); - y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); - x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); - y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); - - objects[i].rect.x = x0; - objects[i].rect.y = y0; - objects[i].rect.width = x1 - x0; - objects[i].rect.height = y1 - y0; - - objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); - cv::Mat mask = cv::Mat(height, width, CV_32FC1, - (float *) mask_pred_result.channel(i)); - mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); - } - - for (const auto &item: objects) { - auto rect = item.rect; - - float array[5]; - array[0] = rect.x; - array[1] = rect.y; - array[2] = rect.x + rect.width; - array[3] = rect.y + rect.height; - array[4] = (float) item.label; - - jfloatArray result_array = env->NewFloatArray(5); - env->SetFloatArrayRegion(result_array, 0, 5, array); - - //add - env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); - } +// ncnn::Extractor ex = yolo_s.create_extractor(); +// ex.input("images", in_pad); +// +// ncnn::Mat out; +// ex.extract("output", out); +// +// ncnn::Mat mask_proto; +// ex.extract("seg", mask_proto); +// +// std::vector strides = {8, 16, 32}; +// std::vector grid_strides; +// generate_grids_and_stride(in_pad.w, in_pad.h, strides, grid_strides); +// +// std::vector proposals; +// std::vector objects8; +// generate_proposals(grid_strides, out, prob_threshold, objects8, 6); +// +// proposals.insert(proposals.end(), objects8.begin(), objects8.end()); +// +// qsort_descent_inplace(proposals); +// +// std::vector picked; +// nms_sorted_bboxes(proposals, picked, nms_threshold); +// +// int count = picked.size(); +// +// ncnn::Mat mask_feat = ncnn::Mat(32, count, sizeof(float)); +// for (int i = 0; i < count; i++) { +// float *mask_feat_ptr = mask_feat.row(i); +// std::memcpy(mask_feat_ptr, proposals[picked[i]].mask_feat.data(), +// sizeof(float) * proposals[picked[i]].mask_feat.size()); +// } +// +// ncnn::Mat mask_pred_result; +// decode_mask(mask_feat, width, height, mask_proto, in_pad, w_pad, h_pad, +// mask_pred_result); +// +// objects.resize(count); +// for (int i = 0; i < count; i++) { +// objects[i] = proposals[picked[i]]; +// +// float x0 = (objects[i].rect.x - (w_pad / 2)) / scale; +// float y0 = (objects[i].rect.y - (h_pad / 2)) / scale; +// float x1 = (objects[i].rect.x + objects[i].rect.width - (w_pad / 2)) / scale; +// float y1 = (objects[i].rect.y + objects[i].rect.height - (h_pad / 2)) / scale; +// +// // clip +// x0 = std::max(std::min(x0, (float) (width - 1)), 0.f); +// y0 = std::max(std::min(y0, (float) (height - 1)), 0.f); +// x1 = std::max(std::min(x1, (float) (width - 1)), 0.f); +// y1 = std::max(std::min(y1, (float) (height - 1)), 0.f); +// +// objects[i].rect.x = x0; +// objects[i].rect.y = y0; +// objects[i].rect.width = x1 - x0; +// objects[i].rect.height = y1 - y0; +// +// objects[i].mask = cv::Mat::zeros(height, width, CV_32FC1); +// cv::Mat mask = cv::Mat(height, width, CV_32FC1, +// (float *) mask_pred_result.channel(i)); +// mask(objects[i].rect).copyTo(objects[i].mask(objects[i].rect)); +// } +// +// for (const auto &item: objects) { +// auto rect = item.rect; +// +// float array[5]; +// array[0] = rect.x; +// array[1] = rect.y; +// array[2] = rect.x + rect.width; +// array[3] = rect.y + rect.height; +// array[4] = (float) item.label; +// +// jfloatArray result_array = env->NewFloatArray(5); +// env->SetFloatArrayRegion(result_array, 0, 5, array); +// +// //add +// env->CallBooleanMethod(segment_array_obj, arraylist_add, result_array); +// } } //检测 diff --git a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt index 352e2b3..955a096 100644 --- a/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt +++ b/app/src/main/java/com/casic/br/ar/app/fragment/CheckManifestFragment.kt @@ -27,23 +27,16 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(requireContext(), "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - for (dic in it.data) { - if (dic.name == RuntimeCache.sceneName) { - binding.contentPanel.visibility = View.VISIBLE - binding.tipsView.visibility = View.GONE + for (dic in RuntimeCache.sceneDicModels) { + if (dic.name == RuntimeCache.sceneName) { + binding.contentPanel.visibility = View.VISIBLE + binding.tipsView.visibility = View.GONE - checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) - return@observe - } else { - binding.tipsView.visibility = View.VISIBLE - binding.contentPanel.visibility = View.GONE - } - } + checkManifestViewModel.getCheckManifestByScene(requireContext(), dic.value) + return + } else { + binding.tipsView.visibility = View.VISIBLE + binding.contentPanel.visibility = View.GONE } } diff --git a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt index b1e937a..f717f82 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/RuntimeCache.kt @@ -9,4 +9,5 @@ var sceneName = "" var inspectionId = "" var mainDicModels: MutableList = ArrayList() + var sceneDicModels: MutableList = ArrayList() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt index 9b8eb2f..611b815 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckManifestActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityCheckManifestBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class CheckManifestActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_check_manifest_l, sceneModels + R.layout.item_check_manifest_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt index fb43a2b..71adcf5 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/CheckModeActivity.kt @@ -30,6 +30,7 @@ import com.casic.br.ar.app.vm.InspectionViewModel import com.casic.br.ar.app.widgets.DetectResultDialog import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.isNumber import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.extensions.timestampToDate @@ -63,11 +64,10 @@ private lateinit var alarmViewModel: AlarmViewModel private lateinit var checkManifestViewModel: CheckManifestViewModel private var mainDicModels: MutableList = ArrayList() - private var sceneDicModels: MutableList = ArrayList() private var isDetectTarget = false private var alarmCode = "" private var checkItemCount = 0 - private var troubleCount = 0 + private var checkPassCount = 0 override fun initOnCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -110,15 +110,6 @@ } } - //detectedScene转为字典值 - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneDicModels = it.data - } - } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] imageFileViewModel.resultModel.observe(this) { @@ -167,7 +158,7 @@ AlertControlDialog.Builder() .setContext(this) .setTitle("温馨提示") - .setMessage("所有检查均已完成,共${targetSet.size}项通过,存在${troubleCount}项隐患,是否结束检查?") + .setMessage("所有检查均已完成,共${checkPassCount}项通过,存在${checkItemCount - checkPassCount}项隐患,是否结束检查?") .setNegativeButton("取消") .setPositiveButton("结束检查") .setOnDialogButtonClickListener(object : @@ -224,7 +215,7 @@ override fun onSegmentation( segmentationOutput: ArrayList, detectOutput: ArrayList ) { - if (segmentationOutput.isEmpty() || detectOutput.isEmpty()) { + if (detectOutput.isEmpty()) { binding.detectView.updateTargetPosition() } else { val segmentationResults = ArrayList() @@ -239,13 +230,11 @@ binding.detectView.updateTargetPosition(segmentationResults, detectResults) - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - lifecycleScope.launch(Dispatchers.Main) { - binding.checkedCountView.text = "${targetSet.size}项" - binding.noCheckCountView.text = "${checkItemCount - targetSet.size}项" + lifecycleScope.launch(Dispatchers.Main) { + detectResults.forEach { + val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] + if (label.isInScene(RuntimeCache.sceneName)) { + targetSet.add(label) } } } @@ -414,13 +403,16 @@ } } - if (warnings == "") { - return + val target = if (warnings == "") { + detectResults.first().type.toString() + } else { + warnings } + //显示弹框 val message = weakReferenceHandler.obtainMessage() message.what = 2024082902 - message.obj = warnings + message.obj = target weakReferenceHandler.sendMessage(message) } } @@ -473,18 +465,18 @@ binding.sceneNameView.text = scene //获取检查清单数目 - for (dic in sceneDicModels) { + for (dic in RuntimeCache.sceneDicModels) { if (dic.name == scene) { checkManifestViewModel.getCheckManifestByScene( context, dic.value ) + + isDetectTarget = true + //调用多模型 + yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) return } } - - isDetectTarget = true - //调用多模型 - yolov8ncnn.loadMultiModel(assets, intArrayOf(0, 1), false) } override fun onCancelClick() { @@ -494,17 +486,24 @@ } 2024082902 -> { - val target = msg.obj as String - if (detectedTargetSet.contains(target)) { - "该目标/隐患已识别过".show(this) - return true - } - //弹框 if (detectResultDialog.isShowing) { return true } + val target = msg.obj as String + if (target.isNumber()) { + if (detectedTargetSet.contains(target)) { + "${LocaleConstant.CLASS_NAMES_ARRAY[target.toInt()]}已识别过".show(this) + return true + } + } else { + if (detectedTargetSet.contains(target)) { + "该隐患已识别过".show(this) + return true + } + } + if (mat.width() > 0 || mat.height() > 0) { detectResultDialog.updateDialogContentView(target, mat, object : DetectResultDialog.OnDialogButtonClickListener { @@ -512,8 +511,14 @@ imageFileViewModel.uploadImage(file) detectedTargetSet.add(target) - troubleCount++ - binding.troubleCountView.text = "${troubleCount}项" + if (target.isNumber()) { + checkPassCount++ + binding.checkedCountView.text = "${checkPassCount}项" + binding.noCheckCountView.text = "${checkItemCount - checkPassCount}项" + if (checkItemCount - checkPassCount == 0) { + stopCheck() + } + } } }).show() } diff --git a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt index 97c9456..6a7faa8 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/HiddenTroubleActivity.kt @@ -6,19 +6,16 @@ import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityHiddenTroubleBinding import com.casic.br.ar.app.model.DictionaryModel -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken +import com.casic.br.ar.app.utils.RuntimeCache import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.Constant class HiddenTroubleActivity : KotlinBaseActivity() { - private val gson by lazy { Gson() } private val marginOffset by lazy { 7.dp2px(this) } override fun initEvent() { @@ -26,14 +23,8 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { - val sceneJsonValue = intent.getStringExtra(Constant.INTENT_PARAM) - //转为实体类 - val sceneModels = gson.fromJson>( - sceneJsonValue, object : TypeToken>() {}.type - ) - val menuAdapter = object : NormalRecyclerAdapter( - R.layout.item_hidden_trouble_l, sceneModels + R.layout.item_hidden_trouble_l, RuntimeCache.sceneDicModels ) { override fun convertView( viewHolder: ViewHolder, position: Int, item: DictionaryModel.DataModel diff --git a/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt index 87e9b3b..8e4849f 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/LibraryActivity.kt @@ -6,9 +6,7 @@ import androidx.lifecycle.ViewModelProvider import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityLibraryBinding -import com.casic.br.ar.app.model.DictionaryModel import com.casic.br.ar.app.model.LibraryModel -import com.casic.br.ar.app.vm.ConfigViewModel import com.casic.br.ar.app.vm.LibraryViewModel import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder @@ -17,7 +15,6 @@ import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.LoadingDialogHub @@ -26,8 +23,6 @@ private val context = this private val marginOffset by lazy { 15.dp2px(this) } private lateinit var libraryViewModel: LibraryViewModel - private lateinit var configViewModel: ConfigViewModel - private var sceneModels: MutableList = ArrayList() override fun initEvent() { @@ -66,7 +61,7 @@ else -> 0 } - viewHolder.setImageResource(R.id.imageView,imageSource) + viewHolder.setImageResource(R.id.imageView, imageSource) .setText(R.id.textView, item.name) viewHolder.getView(R.id.itemRootView) @@ -88,8 +83,8 @@ override fun onItemClicked(position: Int, t: LibraryModel.DataModel) { when (position) { 0 -> navigatePageTo() - 1 -> navigatePageTo(sceneModels.toJson()) - 2 -> navigatePageTo(sceneModels.toJson()) + 1 -> navigatePageTo() + 2 -> navigatePageTo() 3 -> navigatePageTo(t.id) else -> "未实现".show(context) } @@ -97,14 +92,6 @@ }) } } - - configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(this, "securityScene") - configViewModel.dictionary.observe(this) { - if (it.code == 200) { - sceneModels = it.data - } - } } override fun initViewBinding(): ActivityLibraryBinding { diff --git a/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt b/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt index 4bf9880..3adae0c 100644 --- a/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/ar/app/view/MainActivity.kt @@ -5,9 +5,12 @@ import android.view.View import android.widget.LinearLayout import android.widget.TextView +import androidx.lifecycle.ViewModelProvider import com.casic.br.ar.app.R import com.casic.br.ar.app.databinding.ActivityMainBinding import com.casic.br.ar.app.external.Yolov8ncnn +import com.casic.br.ar.app.utils.RuntimeCache +import com.casic.br.ar.app.vm.ConfigViewModel import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity @@ -21,6 +24,7 @@ private val kTag = "MainActivity" private val yolov8ncnn by lazy { Yolov8ncnn() } private val marginOffset by lazy { 25.dp2px(this) } + private lateinit var configViewModel: ConfigViewModel private lateinit var itemAdapter: NormalRecyclerAdapter override fun initEvent() { @@ -37,6 +41,15 @@ } override fun initOnCreate(savedInstanceState: Bundle?) { + //获取到场景字典备用 + configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] + configViewModel.getDictionaryByCode(this, "securityScene") + configViewModel.dictionary.observe(this) { + if (it.code == 200) { + RuntimeCache.sceneDicModels = it.data + } + } + itemAdapter = object : NormalRecyclerAdapter( R.layout.item_main_rv_l, arrayListOf("开始检查", "检查记录", "知识库") ) { diff --git a/app/src/main/java/com/casic/br/ar/app/widgets/DetectResultDialog.kt b/app/src/main/java/com/casic/br/ar/app/widgets/DetectResultDialog.kt index 9df5bc0..df365d8 100644 --- a/app/src/main/java/com/casic/br/ar/app/widgets/DetectResultDialog.kt +++ b/app/src/main/java/com/casic/br/ar/app/widgets/DetectResultDialog.kt @@ -7,10 +7,12 @@ import android.util.Log import com.casic.br.ar.app.databinding.DialogDetectResultBinding import com.casic.br.ar.app.extensions.compressImage +import com.casic.br.ar.app.utils.LocaleConstant import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.pengxh.kt.lite.extensions.binding import com.pengxh.kt.lite.extensions.createImageFileDir import com.pengxh.kt.lite.extensions.initDialogLayoutParams +import com.pengxh.kt.lite.extensions.isNumber import com.pengxh.kt.lite.extensions.saveImage import org.opencv.android.Utils import org.opencv.core.Mat @@ -58,7 +60,12 @@ this.target = target this.mat = mat this.listener = listener - binding.messageView.text = target + + if (target.isNumber()) { + binding.messageView.text = LocaleConstant.CLASS_NAMES_ARRAY[target.toInt()] + } else { + binding.messageView.text = target + } return this }