diff --git a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt index 1ce858b..8936e7b 100644 --- a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt +++ b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt @@ -3,5 +3,5 @@ import com.casic.br.app.model.HiddenTroubleResult interface OnYoloResultSiftCallback { - fun onResultSifted(results: ArrayList) + fun onResultSifted(results: List) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt index 1ce858b..8936e7b 100644 --- a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt +++ b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt @@ -3,5 +3,5 @@ import com.casic.br.app.model.HiddenTroubleResult interface OnYoloResultSiftCallback { - fun onResultSifted(results: ArrayList) + fun onResultSifted(results: List) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt b/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt index 57797c3..7cfb61f 100644 --- a/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt +++ b/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt @@ -6,11 +6,13 @@ import com.casic.br.app.model.HiddenTroubleResult class YoloTargetDetectHelper(private val callback: OnYoloResultSiftCallback) { + + private val kTag = "YoloTargetDetectHelper" + private val hiddenTroubles = ArrayList() + fun siftHiddenTrouble( - segmentationResults: MutableList, detectResults: MutableList, - detectedTargetSet: HashSet + segmentationResults: MutableList, detectResults: MutableList ) { - val hiddenTroubles = ArrayList() //只有有限空间作业才筛选以下隐患 when (RuntimeCache.sceneName) { "有限空间作业" -> { @@ -21,9 +23,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" result.warning = "未佩戴安全帽" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -34,9 +34,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" result.warning = "未着工服" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(17)) { @@ -44,9 +42,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyLine" result.warning = "没有佩戴安全带、安全绳" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -55,9 +51,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerMask" result.warning = "未发现呼吸防护设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含路锥、警戒线 @@ -65,9 +59,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoEnclosure" result.warning = "未发现路锥、警戒线" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含安全告知牌 @@ -78,9 +70,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWarningSign" result.warning = "未发现安全告知牌" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含通风设备 @@ -88,9 +78,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoAirSupply" result.warning = "未发现通风设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含井下照明设备 @@ -98,9 +86,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoLighting" result.warning = "未发现井下照明设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含对讲设备 @@ -108,9 +94,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoIntercom" result.warning = "未发现井下对讲设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含施工三脚架 @@ -118,9 +102,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoTripod" result.warning = "未发现施工三脚架" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含气体检测仪 @@ -128,9 +110,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoGasDetector" result.warning = "未发现气体检测仪" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -144,9 +124,7 @@ val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoCircuitDiagram" result.warning = "配电箱内无电路图" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (detectResults.isContains(35)) { @@ -154,9 +132,7 @@ val result = HiddenTroubleResult() result.alarmCode = "" result.warning = "配电箱内部电线裸露" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (detectResults.isContains(41)) { @@ -164,18 +140,14 @@ val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoJumperWire" result.warning = "配电箱有跨电线" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } else { //不包含警示标识 val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoWarningSign" result.warning = "配电箱无警示标识" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } } @@ -188,9 +160,7 @@ val result = HiddenTroubleResult() result.alarmCode = "" result.warning = "未发现熄火保护装置" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(22)) { @@ -198,9 +168,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" result.warning = "未发现燃气泄漏报警装置" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(4)) { @@ -208,9 +176,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoShutoffValve" result.warning = "未发现切断阀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -221,9 +187,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoHoseJoint" result.warning = "软管有接头或三通" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -231,18 +195,14 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasPipelineRust" result.warning = "腐蚀、锈蚀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (segmentationResults.isContains(0)) { val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasHoseFlexure" result.warning = "软管不可恢复的弯折拉伸" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -251,9 +211,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasPipelineRust" result.warning = "腐蚀、锈蚀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } } diff --git a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt index 1ce858b..8936e7b 100644 --- a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt +++ b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt @@ -3,5 +3,5 @@ import com.casic.br.app.model.HiddenTroubleResult interface OnYoloResultSiftCallback { - fun onResultSifted(results: ArrayList) + fun onResultSifted(results: List) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt b/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt index 57797c3..7cfb61f 100644 --- a/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt +++ b/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt @@ -6,11 +6,13 @@ import com.casic.br.app.model.HiddenTroubleResult class YoloTargetDetectHelper(private val callback: OnYoloResultSiftCallback) { + + private val kTag = "YoloTargetDetectHelper" + private val hiddenTroubles = ArrayList() + fun siftHiddenTrouble( - segmentationResults: MutableList, detectResults: MutableList, - detectedTargetSet: HashSet + segmentationResults: MutableList, detectResults: MutableList ) { - val hiddenTroubles = ArrayList() //只有有限空间作业才筛选以下隐患 when (RuntimeCache.sceneName) { "有限空间作业" -> { @@ -21,9 +23,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" result.warning = "未佩戴安全帽" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -34,9 +34,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" result.warning = "未着工服" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(17)) { @@ -44,9 +42,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyLine" result.warning = "没有佩戴安全带、安全绳" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -55,9 +51,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerMask" result.warning = "未发现呼吸防护设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含路锥、警戒线 @@ -65,9 +59,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoEnclosure" result.warning = "未发现路锥、警戒线" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含安全告知牌 @@ -78,9 +70,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWarningSign" result.warning = "未发现安全告知牌" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含通风设备 @@ -88,9 +78,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoAirSupply" result.warning = "未发现通风设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含井下照明设备 @@ -98,9 +86,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoLighting" result.warning = "未发现井下照明设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含对讲设备 @@ -108,9 +94,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoIntercom" result.warning = "未发现井下对讲设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含施工三脚架 @@ -118,9 +102,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoTripod" result.warning = "未发现施工三脚架" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含气体检测仪 @@ -128,9 +110,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoGasDetector" result.warning = "未发现气体检测仪" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -144,9 +124,7 @@ val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoCircuitDiagram" result.warning = "配电箱内无电路图" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (detectResults.isContains(35)) { @@ -154,9 +132,7 @@ val result = HiddenTroubleResult() result.alarmCode = "" result.warning = "配电箱内部电线裸露" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (detectResults.isContains(41)) { @@ -164,18 +140,14 @@ val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoJumperWire" result.warning = "配电箱有跨电线" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } else { //不包含警示标识 val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoWarningSign" result.warning = "配电箱无警示标识" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } } @@ -188,9 +160,7 @@ val result = HiddenTroubleResult() result.alarmCode = "" result.warning = "未发现熄火保护装置" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(22)) { @@ -198,9 +168,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" result.warning = "未发现燃气泄漏报警装置" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(4)) { @@ -208,9 +176,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoShutoffValve" result.warning = "未发现切断阀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -221,9 +187,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoHoseJoint" result.warning = "软管有接头或三通" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -231,18 +195,14 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasPipelineRust" result.warning = "腐蚀、锈蚀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (segmentationResults.isContains(0)) { val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasHoseFlexure" result.warning = "软管不可恢复的弯折拉伸" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -251,9 +211,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasPipelineRust" result.warning = "腐蚀、锈蚀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } } diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index 64a359d..4b2bb77 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -6,7 +6,6 @@ import android.os.Bundle import android.os.Handler import android.os.Message -import android.util.Log import android.view.SurfaceHolder import android.view.View import android.view.WindowManager @@ -68,7 +67,7 @@ private val weakReferenceHandler by lazy { WeakReferenceHandler(this) } private val detectResultDialog by lazy { DetectResultDialog(this) } private val detectHelper by lazy { YoloTargetDetectHelper(this) } - private val troubleStack by lazy { Stack() } + private val troubleSiftCacheStack by lazy { Stack>() } private lateinit var inspectionViewModel: InspectionViewModel private lateinit var configViewModel: ConfigViewModel private lateinit var imageFileViewModel: ImageFileViewModel @@ -128,8 +127,15 @@ } } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.resultModel.observe(this) { + if (it == 200) { + "提交成功".show(context) + detectedTargetSet.add(result.warning) + } + } + + imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] imageFileViewModel.resultModel.observe(this) { if (it.code == 200) { //报警图片提交成功后,提交隐患 @@ -143,24 +149,19 @@ timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - runOnUiThread { - if (troubleStack.isNotEmpty() && !detectResultDialog.isShowing) { - val hiddenTroubleResult = troubleStack.pop() - //显示差集的隐患 - if (mat.width() > 0 || mat.height() > 0) { - detectResultDialog.updateDialogContentView(hiddenTroubleResult, mat, - object : DetectResultDialog.OnDialogButtonClickListener { - override fun onConfirmClick( - file: File, result: HiddenTroubleResult - ) { - this@StartCheckByYoloActivity.result = hiddenTroubleResult - imageFileViewModel.uploadImage(file) - detectedTargetSet.add(hiddenTroubleResult.warning) - } - }).show() + if (troubleSiftCacheStack.isNotEmpty()) { + //筛选出没有添加过的隐患 + val temp = ArrayList() + troubleSiftCacheStack.pop().forEach { + if (!detectedTargetSet.contains(it.warning)) { + temp.add(it) } - } else { - Log.d(kTag, "run: 隐患缓存为空") + } + if (temp.isNotEmpty()) { + val message = weakReferenceHandler.obtainMessage() + message.what = 2024092601 + message.obj = temp.first() + weakReferenceHandler.sendMessage(message) } } } @@ -248,6 +249,7 @@ if (it.resultCode == RESULT_OK) { val sceneName = it.data?.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) + binding.listTagView.visibility = View.VISIBLE //暂停算法 yolov8ncnn.onPause() @@ -265,6 +267,8 @@ lifecycleScope.launch(Dispatchers.Main) { yolov8ncnn.closeCamera() + timer.cancel() + //有些手机性能跟不上,检查界面已经销毁,线程还在继续跑,导致C++出现野指针,延迟1s关闭界面 delay(1000) @@ -295,29 +299,33 @@ } //实时筛选隐患结果 - detectHelper.siftHiddenTrouble(segmentationResults, detectResults, detectedTargetSet) + detectHelper.siftHiddenTrouble(segmentationResults, detectResults) detectResults.forEach { val label = LocaleConstant.TARGET_NAMES_ARRAY[it.type] targetSet.add(label) - if (RuntimeCache.sceneName == "有限空间作业") { - when (it.type) { - 37 -> RuntimeCache.detectResult.add(0) - 5, 14, 24 -> RuntimeCache.detectResult.add(1) - 0 -> RuntimeCache.detectResult.add(2) - 50, 51 -> RuntimeCache.detectResult.add(3) - 25 -> RuntimeCache.detectResult.add(4) - 9 -> RuntimeCache.detectResult.add(5) - 18 -> RuntimeCache.detectResult.add(6) - 33 -> RuntimeCache.detectResult.add(7) + when (RuntimeCache.sceneName) { + "有限空间作业" -> { + when (it.type) { + 37 -> RuntimeCache.detectResult.add(0) + 5, 14, 24 -> RuntimeCache.detectResult.add(1) + 0 -> RuntimeCache.detectResult.add(2) + 50, 51 -> RuntimeCache.detectResult.add(3) + 25 -> RuntimeCache.detectResult.add(4) + 9 -> RuntimeCache.detectResult.add(5) + 18 -> RuntimeCache.detectResult.add(6) + 33 -> RuntimeCache.detectResult.add(7) + } } - } else { -// when (it.type) { -// 2 -> RuntimeCache.detectResult.add(1) -// 31, 32 -> RuntimeCache.detectResult.add(0) -// 34 -> RuntimeCache.detectResult.add(0) -// 22 -> RuntimeCache.detectResult.add(4) -// 4 -> RuntimeCache.detectResult.add(3) -// } + + "非居用户" -> { + when (it.type) { + 2 -> RuntimeCache.detectResult.add(1) + 31, 32 -> RuntimeCache.detectResult.add(0) + 34 -> RuntimeCache.detectResult.add(0) + 22 -> RuntimeCache.detectResult.add(4) + 4 -> RuntimeCache.detectResult.add(3) + } + } } } runOnUiThread { @@ -347,11 +355,13 @@ weakReferenceHandler.sendMessage(message) } - override fun onResultSifted(results: ArrayList) { + override fun onResultSifted(results: List) { if (results.isEmpty()) { return } - troubleStack.push(results.first()) + + //将隐患结果一帧一帧的缓存 + troubleSiftCacheStack.push(results) } override fun handleMessage(msg: Message): Boolean { @@ -385,6 +395,24 @@ } }).build().show() } + + 2024092601 -> { + if (!detectResultDialog.isShowing) { + val hiddenTroubleResult = msg.obj as HiddenTroubleResult + //显示差集的隐患 + if (mat.width() > 0 || mat.height() > 0) { + detectResultDialog.updateDialogContentView(hiddenTroubleResult, mat, + object : DetectResultDialog.OnDialogButtonClickListener { + override fun onConfirmClick( + file: File, result: HiddenTroubleResult + ) { + this@StartCheckByYoloActivity.result = hiddenTroubleResult + imageFileViewModel.uploadImage(file) + } + }).show() + } + } + } } return true } diff --git a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt index 1ce858b..8936e7b 100644 --- a/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt +++ b/app/src/main/java/com/casic/br/app/callback/OnYoloResultSiftCallback.kt @@ -3,5 +3,5 @@ import com.casic.br.app.model.HiddenTroubleResult interface OnYoloResultSiftCallback { - fun onResultSifted(results: ArrayList) + fun onResultSifted(results: List) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt b/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt index 57797c3..7cfb61f 100644 --- a/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt +++ b/app/src/main/java/com/casic/br/app/utils/YoloTargetDetectHelper.kt @@ -6,11 +6,13 @@ import com.casic.br.app.model.HiddenTroubleResult class YoloTargetDetectHelper(private val callback: OnYoloResultSiftCallback) { + + private val kTag = "YoloTargetDetectHelper" + private val hiddenTroubles = ArrayList() + fun siftHiddenTrouble( - segmentationResults: MutableList, detectResults: MutableList, - detectedTargetSet: HashSet + segmentationResults: MutableList, detectResults: MutableList ) { - val hiddenTroubles = ArrayList() //只有有限空间作业才筛选以下隐患 when (RuntimeCache.sceneName) { "有限空间作业" -> { @@ -21,9 +23,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" result.warning = "未佩戴安全帽" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -34,9 +34,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" result.warning = "未着工服" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(17)) { @@ -44,9 +42,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyLine" result.warning = "没有佩戴安全带、安全绳" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -55,9 +51,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWorkerMask" result.warning = "未发现呼吸防护设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含路锥、警戒线 @@ -65,9 +59,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoEnclosure" result.warning = "未发现路锥、警戒线" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含安全告知牌 @@ -78,9 +70,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoWarningSign" result.warning = "未发现安全告知牌" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含通风设备 @@ -88,9 +78,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoAirSupply" result.warning = "未发现通风设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含井下照明设备 @@ -98,9 +86,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoLighting" result.warning = "未发现井下照明设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含对讲设备 @@ -108,9 +94,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoIntercom" result.warning = "未发现井下对讲设备" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含施工三脚架 @@ -118,9 +102,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoTripod" result.warning = "未发现施工三脚架" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } //结果不包含气体检测仪 @@ -128,9 +110,7 @@ val result = HiddenTroubleResult() result.alarmCode = "ConfinedSpaceHasNoGasDetector" result.warning = "未发现气体检测仪" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -144,9 +124,7 @@ val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoCircuitDiagram" result.warning = "配电箱内无电路图" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (detectResults.isContains(35)) { @@ -154,9 +132,7 @@ val result = HiddenTroubleResult() result.alarmCode = "" result.warning = "配电箱内部电线裸露" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (detectResults.isContains(41)) { @@ -164,18 +140,14 @@ val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoJumperWire" result.warning = "配电箱有跨电线" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } else { //不包含警示标识 val result = HiddenTroubleResult() result.alarmCode = "DistributionBoxHasNoWarningSign" result.warning = "配电箱无警示标识" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } } @@ -188,9 +160,7 @@ val result = HiddenTroubleResult() result.alarmCode = "" result.warning = "未发现熄火保护装置" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(22)) { @@ -198,9 +168,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" result.warning = "未发现燃气泄漏报警装置" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (!detectResults.isContains(4)) { @@ -208,9 +176,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoShutoffValve" result.warning = "未发现切断阀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -221,9 +187,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasNoHoseJoint" result.warning = "软管有接头或三通" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -231,18 +195,14 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasPipelineRust" result.warning = "腐蚀、锈蚀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } if (segmentationResults.isContains(0)) { val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasHoseFlexure" result.warning = "软管不可恢复的弯折拉伸" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } @@ -251,9 +211,7 @@ val result = HiddenTroubleResult() result.alarmCode = "NonResidentUserHasPipelineRust" result.warning = "腐蚀、锈蚀" - if (!detectedTargetSet.contains(result.warning)) { - hiddenTroubles.add(result) - } + hiddenTroubles.add(result) } } } diff --git a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt index 64a359d..4b2bb77 100644 --- a/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt +++ b/app/src/main/java/com/casic/br/app/view/StartCheckByYoloActivity.kt @@ -6,7 +6,6 @@ import android.os.Bundle import android.os.Handler import android.os.Message -import android.util.Log import android.view.SurfaceHolder import android.view.View import android.view.WindowManager @@ -68,7 +67,7 @@ private val weakReferenceHandler by lazy { WeakReferenceHandler(this) } private val detectResultDialog by lazy { DetectResultDialog(this) } private val detectHelper by lazy { YoloTargetDetectHelper(this) } - private val troubleStack by lazy { Stack() } + private val troubleSiftCacheStack by lazy { Stack>() } private lateinit var inspectionViewModel: InspectionViewModel private lateinit var configViewModel: ConfigViewModel private lateinit var imageFileViewModel: ImageFileViewModel @@ -128,8 +127,15 @@ } } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.resultModel.observe(this) { + if (it == 200) { + "提交成功".show(context) + detectedTargetSet.add(result.warning) + } + } + + imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] imageFileViewModel.resultModel.observe(this) { if (it.code == 200) { //报警图片提交成功后,提交隐患 @@ -143,24 +149,19 @@ timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - runOnUiThread { - if (troubleStack.isNotEmpty() && !detectResultDialog.isShowing) { - val hiddenTroubleResult = troubleStack.pop() - //显示差集的隐患 - if (mat.width() > 0 || mat.height() > 0) { - detectResultDialog.updateDialogContentView(hiddenTroubleResult, mat, - object : DetectResultDialog.OnDialogButtonClickListener { - override fun onConfirmClick( - file: File, result: HiddenTroubleResult - ) { - this@StartCheckByYoloActivity.result = hiddenTroubleResult - imageFileViewModel.uploadImage(file) - detectedTargetSet.add(hiddenTroubleResult.warning) - } - }).show() + if (troubleSiftCacheStack.isNotEmpty()) { + //筛选出没有添加过的隐患 + val temp = ArrayList() + troubleSiftCacheStack.pop().forEach { + if (!detectedTargetSet.contains(it.warning)) { + temp.add(it) } - } else { - Log.d(kTag, "run: 隐患缓存为空") + } + if (temp.isNotEmpty()) { + val message = weakReferenceHandler.obtainMessage() + message.what = 2024092601 + message.obj = temp.first() + weakReferenceHandler.sendMessage(message) } } } @@ -248,6 +249,7 @@ if (it.resultCode == RESULT_OK) { val sceneName = it.data?.getStringExtra("sceneName").toString() binding.titleView.setTitle(sceneName) + binding.listTagView.visibility = View.VISIBLE //暂停算法 yolov8ncnn.onPause() @@ -265,6 +267,8 @@ lifecycleScope.launch(Dispatchers.Main) { yolov8ncnn.closeCamera() + timer.cancel() + //有些手机性能跟不上,检查界面已经销毁,线程还在继续跑,导致C++出现野指针,延迟1s关闭界面 delay(1000) @@ -295,29 +299,33 @@ } //实时筛选隐患结果 - detectHelper.siftHiddenTrouble(segmentationResults, detectResults, detectedTargetSet) + detectHelper.siftHiddenTrouble(segmentationResults, detectResults) detectResults.forEach { val label = LocaleConstant.TARGET_NAMES_ARRAY[it.type] targetSet.add(label) - if (RuntimeCache.sceneName == "有限空间作业") { - when (it.type) { - 37 -> RuntimeCache.detectResult.add(0) - 5, 14, 24 -> RuntimeCache.detectResult.add(1) - 0 -> RuntimeCache.detectResult.add(2) - 50, 51 -> RuntimeCache.detectResult.add(3) - 25 -> RuntimeCache.detectResult.add(4) - 9 -> RuntimeCache.detectResult.add(5) - 18 -> RuntimeCache.detectResult.add(6) - 33 -> RuntimeCache.detectResult.add(7) + when (RuntimeCache.sceneName) { + "有限空间作业" -> { + when (it.type) { + 37 -> RuntimeCache.detectResult.add(0) + 5, 14, 24 -> RuntimeCache.detectResult.add(1) + 0 -> RuntimeCache.detectResult.add(2) + 50, 51 -> RuntimeCache.detectResult.add(3) + 25 -> RuntimeCache.detectResult.add(4) + 9 -> RuntimeCache.detectResult.add(5) + 18 -> RuntimeCache.detectResult.add(6) + 33 -> RuntimeCache.detectResult.add(7) + } } - } else { -// when (it.type) { -// 2 -> RuntimeCache.detectResult.add(1) -// 31, 32 -> RuntimeCache.detectResult.add(0) -// 34 -> RuntimeCache.detectResult.add(0) -// 22 -> RuntimeCache.detectResult.add(4) -// 4 -> RuntimeCache.detectResult.add(3) -// } + + "非居用户" -> { + when (it.type) { + 2 -> RuntimeCache.detectResult.add(1) + 31, 32 -> RuntimeCache.detectResult.add(0) + 34 -> RuntimeCache.detectResult.add(0) + 22 -> RuntimeCache.detectResult.add(4) + 4 -> RuntimeCache.detectResult.add(3) + } + } } } runOnUiThread { @@ -347,11 +355,13 @@ weakReferenceHandler.sendMessage(message) } - override fun onResultSifted(results: ArrayList) { + override fun onResultSifted(results: List) { if (results.isEmpty()) { return } - troubleStack.push(results.first()) + + //将隐患结果一帧一帧的缓存 + troubleSiftCacheStack.push(results) } override fun handleMessage(msg: Message): Boolean { @@ -385,6 +395,24 @@ } }).build().show() } + + 2024092601 -> { + if (!detectResultDialog.isShowing) { + val hiddenTroubleResult = msg.obj as HiddenTroubleResult + //显示差集的隐患 + if (mat.width() > 0 || mat.height() > 0) { + detectResultDialog.updateDialogContentView(hiddenTroubleResult, mat, + object : DetectResultDialog.OnDialogButtonClickListener { + override fun onConfirmClick( + file: File, result: HiddenTroubleResult + ) { + this@StartCheckByYoloActivity.result = hiddenTroubleResult + imageFileViewModel.uploadImage(file) + } + }).show() + } + } + } } return true } diff --git a/app/src/main/java/com/casic/br/app/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/app/vm/AlarmViewModel.kt index 84d8d0a..500fdc2 100644 --- a/app/src/main/java/com/casic/br/app/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/app/vm/AlarmViewModel.kt @@ -1,6 +1,7 @@ package com.casic.br.app.vm import android.content.Context +import androidx.lifecycle.MutableLiveData import com.casic.br.app.extensions.getResponseCode import com.casic.br.app.extensions.getResponseMessage import com.casic.br.app.retrofit.RetrofitServiceManager @@ -9,13 +10,16 @@ import com.pengxh.kt.lite.extensions.show class AlarmViewModel : BaseViewModel() { + + val resultModel = MutableLiveData() + fun uploadDetectTargetAlarm( context: Context, alarmCode: String, alarmImgPath: String ) = launch({ val response = RetrofitServiceManager.uploadDetectTargetAlarm(alarmCode, alarmImgPath) val responseCode = response.getResponseCode() if (responseCode == 200) { - "提交成功".show(context) + resultModel.value = 200 } else { response.getResponseMessage().show(context) }