diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt index 43db667..d0dece7 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt @@ -8,7 +8,6 @@ import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Part -import retrofit2.http.PartMap import retrofit2.http.Path import retrofit2.http.Query @@ -160,20 +159,6 @@ ): String /** - * 获取场景 - */ - @Multipart - @POST("/getScene") - suspend fun getScene(@PartMap body: MutableMap): String - - /** - * 获取画面识别结果 - */ - @Multipart - @POST("detect") - suspend fun getRecognizeResult(@PartMap body: MutableMap): String - - /** * 获取知识库分类列表 */ @GET("/knowledge-class/list") diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt index 43db667..d0dece7 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt @@ -8,7 +8,6 @@ import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Part -import retrofit2.http.PartMap import retrofit2.http.Path import retrofit2.http.Query @@ -160,20 +159,6 @@ ): String /** - * 获取场景 - */ - @Multipart - @POST("/getScene") - suspend fun getScene(@PartMap body: MutableMap): String - - /** - * 获取画面识别结果 - */ - @Multipart - @POST("detect") - suspend fun getRecognizeResult(@PartMap body: MutableMap): String - - /** * 获取知识库分类列表 */ @GET("/knowledge-class/list") diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt index beedfe1..4ab071e 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt @@ -11,7 +11,6 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File @@ -26,13 +25,6 @@ RetrofitFactory.createRetrofit(httpConfig, timeout = 20) } - private val aiApi by lazy { - val httpConfig = SaveKeyValues.getValue( - LocaleConstant.AI_SERVER_CONFIG, LocaleConstant.AI_BASE_URL - ) as String - RetrofitFactory.createRetrofit(httpConfig, timeout = 20) - } - private val gson by lazy { Gson() } private val typeToken = object : TypeToken>>() {}.type @@ -221,26 +213,6 @@ } /** - * 获取场景 - * */ - suspend fun getScene(base64: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - return aiApi.getScene(map) - } - - /** - * 获取画面识别结果 - * */ - suspend fun getRecognizeResult(base64: String, scene: String, inspectionId: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - map["scene"] = scene.toRequestBody() - map["xunjian_id"] = inspectionId.toRequestBody() - return aiApi.getRecognizeResult(map) - } - - /** * 获取知识库分类列表 */ suspend fun getLibraryList(): String { diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt index 43db667..d0dece7 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt @@ -8,7 +8,6 @@ import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Part -import retrofit2.http.PartMap import retrofit2.http.Path import retrofit2.http.Query @@ -160,20 +159,6 @@ ): String /** - * 获取场景 - */ - @Multipart - @POST("/getScene") - suspend fun getScene(@PartMap body: MutableMap): String - - /** - * 获取画面识别结果 - */ - @Multipart - @POST("detect") - suspend fun getRecognizeResult(@PartMap body: MutableMap): String - - /** * 获取知识库分类列表 */ @GET("/knowledge-class/list") diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt index beedfe1..4ab071e 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt @@ -11,7 +11,6 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File @@ -26,13 +25,6 @@ RetrofitFactory.createRetrofit(httpConfig, timeout = 20) } - private val aiApi by lazy { - val httpConfig = SaveKeyValues.getValue( - LocaleConstant.AI_SERVER_CONFIG, LocaleConstant.AI_BASE_URL - ) as String - RetrofitFactory.createRetrofit(httpConfig, timeout = 20) - } - private val gson by lazy { Gson() } private val typeToken = object : TypeToken>>() {}.type @@ -221,26 +213,6 @@ } /** - * 获取场景 - * */ - suspend fun getScene(base64: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - return aiApi.getScene(map) - } - - /** - * 获取画面识别结果 - * */ - suspend fun getRecognizeResult(base64: String, scene: String, inspectionId: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - map["scene"] = scene.toRequestBody() - map["xunjian_id"] = inspectionId.toRequestBody() - return aiApi.getRecognizeResult(map) - } - - /** * 获取知识库分类列表 */ suspend fun getLibraryList(): String { diff --git a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt index b4d468f..05ea8c7 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt @@ -33,112 +33,49 @@ ) } - val CLASS_NAMES_ARRAY = arrayListOf( - "三脚架", - "三通", - "专用软管", - "人", - "切断阀", - "危险告知牌", - "压力测试仪", - "压力表", - "反光衣", - "呼吸面罩", - "喉箍", - "四合一", - "圆头水枪", - "头", - "安全告知牌", - "安全帽", - "安全标识", - "安全绳", - "对讲设备", - "尖头水枪", - "工服", - "开关", - "报警装置", - "接头", - "施工路牌", - "气体检测报警仪", - "水带", - "水带_矩形", - "流量计", - "消火栓箱", - "灭火器", - "灶台", - "灶眼", - "照明设备", - "熄火保护", - "电线暴露", - "电路图", - "警戒线", - "调压器", - "调长器", - "贴纸", - "跨电线", - "路锥", - "过滤器", - "配电箱", - "长柄阀门", - "闪光灯亮", - "闪光灯灭", - "阀门", - "非专用软管", - "风管", - "鼓风机" + val TARGET_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "标准软管", "人", "切断阀", "危险告知牌", "压力表", + "压力表", "防护服", "呼气器", "喉箍", "气体检测报警仪", "水枪", "", + "安全告知牌", "安全帽", "安全警示标识", "安全绳", "对讲设备", "水枪", "工服", + "开关", "燃气探测器", "接头", "施工路牌", "气体检测报警仪", "水带", "水带", + "流量计", "消火栓箱", "灭火器", "灶台", "灶具", "照明设备", "熄火保护", + "电线裸露", "电路图", "警戒线", "调压器", "调长器", "贴纸", "跨电线", + "路锥", "过滤器", "配电箱外部", "长柄阀门", "", "", "阀门", + "非标准软管", "送风设备", "送风设备" ) - val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "腐蚀、铁锈", "龟裂") + val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "铁锈", "龟裂") - val HIDDEN_TROUBLE_ARRAY = arrayOf( - "配电箱无警示标识", - "配电箱内无电路图", - "配电箱内部电线裸露", - "配电箱有跨电线", - "未佩戴安全帽", - "未着工服", - "没有佩戴安全带、安全绳", - "未发现呼吸防护设备", - "未发现路锥、警戒线", - "未发现安全告知牌", - "未发现通风设备", - "未发现井下照明设备", - "未发现井下对讲设备", - "未发现施工三脚架", - "未发现气体检测仪", - "非专用软管", - "软管有接头或三通", - "未发现切断阀", - "未发现熄火保护装置", - "未发现燃气泄漏报警装置" - ) - - //配电箱 - val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( - "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" - ) - - //有限空间作业 - val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( - "安全帽", "呼吸面罩", "施工路牌", "安全告知牌", "危险告知牌", "警戒线", - "路锥", "三脚架", "对讲机", "反光衣", "照明设备", "气体检测仪", "安全绳", - "灭火器", "风管", "鼓风机", "人" - ) - - //非居 - val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( - "三通", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头", "灶台", - "灶眼", + //配电箱外部 + val P_D_X_SCENE_ARRAY = arrayListOf( + "配电箱外部", "配电箱内部", "安全警示标识", "开关", "开关标识", "电路图", "跨电线" ) //调压站 - val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( - "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + val T_Y_Z_SCENE_ARRAY = arrayListOf( + "调压器", "过滤器", "阀门", "压力表", "调长器", "流量计", "安全阀" ) //建筑消防 - val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( - "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形" + val J_Z_X_F_SCENE_ARRAY = arrayListOf( + "消火栓箱", "水枪", "水带", "消火栓", "灭火器" + ) + + //有限空间作业 + val Y_X_K_J_Z_Y_SCENE_ARRAY = arrayListOf( + "路锥", "警戒线", "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", "呼吸器", + "对讲设备", "照明设备", "气体检测报警仪", "工服", "防护服", "安全帽" + ) + + //非居 + val F_Z_M_SCENE_ARRAY = arrayListOf( + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", "燃气管道", "切断阀", + "阀门", "标准软管", "非标准软管" + ) + + //居民用户 + val Z_M_SCENE_ARRAY = arrayListOf( + "标准软管", "非标准软管", "灶具", "熄火保护" ) /** @@ -157,8 +94,5 @@ const val ACCOUNT = "account" const val PASSWORD = "password" const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" - const val BASE_IP = "111.198.10.15:22003" - const val SERVER_BASE_URL = "http://${BASE_IP}" - const val AI_SERVER_CONFIG = "aiServerConfig" - const val AI_BASE_URL = "http://192.168.206.248:5000" + const val SERVER_BASE_URL = "http://111.198.10.15:22003" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt index 43db667..d0dece7 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt @@ -8,7 +8,6 @@ import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Part -import retrofit2.http.PartMap import retrofit2.http.Path import retrofit2.http.Query @@ -160,20 +159,6 @@ ): String /** - * 获取场景 - */ - @Multipart - @POST("/getScene") - suspend fun getScene(@PartMap body: MutableMap): String - - /** - * 获取画面识别结果 - */ - @Multipart - @POST("detect") - suspend fun getRecognizeResult(@PartMap body: MutableMap): String - - /** * 获取知识库分类列表 */ @GET("/knowledge-class/list") diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt index beedfe1..4ab071e 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt @@ -11,7 +11,6 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File @@ -26,13 +25,6 @@ RetrofitFactory.createRetrofit(httpConfig, timeout = 20) } - private val aiApi by lazy { - val httpConfig = SaveKeyValues.getValue( - LocaleConstant.AI_SERVER_CONFIG, LocaleConstant.AI_BASE_URL - ) as String - RetrofitFactory.createRetrofit(httpConfig, timeout = 20) - } - private val gson by lazy { Gson() } private val typeToken = object : TypeToken>>() {}.type @@ -221,26 +213,6 @@ } /** - * 获取场景 - * */ - suspend fun getScene(base64: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - return aiApi.getScene(map) - } - - /** - * 获取画面识别结果 - * */ - suspend fun getRecognizeResult(base64: String, scene: String, inspectionId: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - map["scene"] = scene.toRequestBody() - map["xunjian_id"] = inspectionId.toRequestBody() - return aiApi.getRecognizeResult(map) - } - - /** * 获取知识库分类列表 */ suspend fun getLibraryList(): String { diff --git a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt index b4d468f..05ea8c7 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt @@ -33,112 +33,49 @@ ) } - val CLASS_NAMES_ARRAY = arrayListOf( - "三脚架", - "三通", - "专用软管", - "人", - "切断阀", - "危险告知牌", - "压力测试仪", - "压力表", - "反光衣", - "呼吸面罩", - "喉箍", - "四合一", - "圆头水枪", - "头", - "安全告知牌", - "安全帽", - "安全标识", - "安全绳", - "对讲设备", - "尖头水枪", - "工服", - "开关", - "报警装置", - "接头", - "施工路牌", - "气体检测报警仪", - "水带", - "水带_矩形", - "流量计", - "消火栓箱", - "灭火器", - "灶台", - "灶眼", - "照明设备", - "熄火保护", - "电线暴露", - "电路图", - "警戒线", - "调压器", - "调长器", - "贴纸", - "跨电线", - "路锥", - "过滤器", - "配电箱", - "长柄阀门", - "闪光灯亮", - "闪光灯灭", - "阀门", - "非专用软管", - "风管", - "鼓风机" + val TARGET_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "标准软管", "人", "切断阀", "危险告知牌", "压力表", + "压力表", "防护服", "呼气器", "喉箍", "气体检测报警仪", "水枪", "", + "安全告知牌", "安全帽", "安全警示标识", "安全绳", "对讲设备", "水枪", "工服", + "开关", "燃气探测器", "接头", "施工路牌", "气体检测报警仪", "水带", "水带", + "流量计", "消火栓箱", "灭火器", "灶台", "灶具", "照明设备", "熄火保护", + "电线裸露", "电路图", "警戒线", "调压器", "调长器", "贴纸", "跨电线", + "路锥", "过滤器", "配电箱外部", "长柄阀门", "", "", "阀门", + "非标准软管", "送风设备", "送风设备" ) - val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "腐蚀、铁锈", "龟裂") + val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "铁锈", "龟裂") - val HIDDEN_TROUBLE_ARRAY = arrayOf( - "配电箱无警示标识", - "配电箱内无电路图", - "配电箱内部电线裸露", - "配电箱有跨电线", - "未佩戴安全帽", - "未着工服", - "没有佩戴安全带、安全绳", - "未发现呼吸防护设备", - "未发现路锥、警戒线", - "未发现安全告知牌", - "未发现通风设备", - "未发现井下照明设备", - "未发现井下对讲设备", - "未发现施工三脚架", - "未发现气体检测仪", - "非专用软管", - "软管有接头或三通", - "未发现切断阀", - "未发现熄火保护装置", - "未发现燃气泄漏报警装置" - ) - - //配电箱 - val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( - "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" - ) - - //有限空间作业 - val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( - "安全帽", "呼吸面罩", "施工路牌", "安全告知牌", "危险告知牌", "警戒线", - "路锥", "三脚架", "对讲机", "反光衣", "照明设备", "气体检测仪", "安全绳", - "灭火器", "风管", "鼓风机", "人" - ) - - //非居 - val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( - "三通", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头", "灶台", - "灶眼", + //配电箱外部 + val P_D_X_SCENE_ARRAY = arrayListOf( + "配电箱外部", "配电箱内部", "安全警示标识", "开关", "开关标识", "电路图", "跨电线" ) //调压站 - val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( - "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + val T_Y_Z_SCENE_ARRAY = arrayListOf( + "调压器", "过滤器", "阀门", "压力表", "调长器", "流量计", "安全阀" ) //建筑消防 - val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( - "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形" + val J_Z_X_F_SCENE_ARRAY = arrayListOf( + "消火栓箱", "水枪", "水带", "消火栓", "灭火器" + ) + + //有限空间作业 + val Y_X_K_J_Z_Y_SCENE_ARRAY = arrayListOf( + "路锥", "警戒线", "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", "呼吸器", + "对讲设备", "照明设备", "气体检测报警仪", "工服", "防护服", "安全帽" + ) + + //非居 + val F_Z_M_SCENE_ARRAY = arrayListOf( + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", "燃气管道", "切断阀", + "阀门", "标准软管", "非标准软管" + ) + + //居民用户 + val Z_M_SCENE_ARRAY = arrayListOf( + "标准软管", "非标准软管", "灶具", "熄火保护" ) /** @@ -157,8 +94,5 @@ const val ACCOUNT = "account" const val PASSWORD = "password" const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" - const val BASE_IP = "111.198.10.15:22003" - const val SERVER_BASE_URL = "http://${BASE_IP}" - const val AI_SERVER_CONFIG = "aiServerConfig" - const val AI_BASE_URL = "http://192.168.206.248:5000" + const val SERVER_BASE_URL = "http://111.198.10.15:22003" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt new file mode 100644 index 0000000..26a7790 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt @@ -0,0 +1,232 @@ +package com.casic.br.ar.app.utils + +import com.casic.br.ar.app.extensions.isContains +import com.casic.br.ar.app.external.YoloResult +import com.casic.br.ar.app.model.HiddenTroubleResult + +class YoloTargetDetectHelper { + + private val kTag = "YoloTargetDetectHelper" + + @JvmField + @Volatile + var hiddenTroubles = ArrayList() + + fun siftHiddenTrouble( + segmentationResults: MutableList, detectResults: MutableList + ) { + //只有有限空间作业才筛选以下隐患 + when (RuntimeCache.sceneName) { + "有限空间作业" -> { + //结果包含人 + if (detectResults.isContains(3)) { + if (!detectResults.isContains(20) || !detectResults.isContains(8)) { + //不包含工服/防护服 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" + result.warning = "未穿工服/防护服" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(15)) { + //不包含安全帽 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" + result.warning = "未佩戴安全帽" + hiddenTroubles.add(result) + } + } + + //结果不包含呼吸防护设备 + if (!detectResults.isContains(9)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerMask" + result.warning = "现场无呼吸器" + hiddenTroubles.add(result) + } + + //结果不包含路锥、警戒线 + if (!detectResults.isContains(42) || !detectResults.isContains(37)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoEnclosure" + result.warning = "现场无围挡设施" + hiddenTroubles.add(result) + } + + //结果不包含安全告知牌 + if (!detectResults.isContains(14) || + !detectResults.isContains(5) || + !detectResults.isContains(24) + ) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWarningSign" + result.warning = "现场无安全告知牌" + hiddenTroubles.add(result) + } + + //TODO 新类型 + if (!detectResults.isContains(999999)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoJobInformationSign" + result.warning = "现场无作业信息公示牌" + hiddenTroubles.add(result) + } + + //结果不包含通风设备 + if (!detectResults.isContains(50) || !detectResults.isContains(51)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoAirSupply" + result.warning = "现场无送风设备" + hiddenTroubles.add(result) + } + + //结果不包含井下照明设备 + if (!detectResults.isContains(33)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoLighting" + result.warning = "现场无照明设备" + hiddenTroubles.add(result) + } + + //结果不包含对讲设备 + if (!detectResults.isContains(18)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoIntercom" + result.warning = "现场无对讲设备" + hiddenTroubles.add(result) + } + + //结果不包含施工三脚架 + if (!detectResults.isContains(0)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoTripod" + result.warning = "现场无三脚架" + hiddenTroubles.add(result) + } + + //结果不包含气体检测仪 + if (!detectResults.isContains(25)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoGasDetector" + result.warning = "现场无气体检测报警仪" + hiddenTroubles.add(result) + } + } + + "配电箱" -> { + //结果包含配电箱 + if (detectResults.isContains(44)) { + //且还包括开关 + if (detectResults.isContains(21)) { + if (!detectResults.isContains(36)) { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoCircuitDiagram" + result.warning = "配电箱内无电路图" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(35)) { + //包含电线裸露 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasExposedWire" + result.warning = "配电箱内部电线裸露" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(41)) { + //包含跨电线 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoJumperWire" + result.warning = "配电箱箱体和箱盖未跨接" + hiddenTroubles.add(result) + } + } else { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoWarningSign" + result.warning = "配电箱无警示标识" + hiddenTroubles.add(result) + } + } + } + + "非居用户" -> { + if (segmentationResults.isContains(4)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasPipelineRust" + result.warning = "管道腐蚀锈蚀" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(22)) { + //不包含燃气泄漏报警装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoAlarmDevice" + result.warning = "无燃气泄漏报警装置" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(4)) { + //不包含切断阀 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoShutoffValve" + result.warning = "未设置切断阀" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护装置" + hiddenTroubles.add(result) + } + } + } + + "居民用户" -> { + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护" + hiddenTroubles.add(result) + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt index 43db667..d0dece7 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt @@ -8,7 +8,6 @@ import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Part -import retrofit2.http.PartMap import retrofit2.http.Path import retrofit2.http.Query @@ -160,20 +159,6 @@ ): String /** - * 获取场景 - */ - @Multipart - @POST("/getScene") - suspend fun getScene(@PartMap body: MutableMap): String - - /** - * 获取画面识别结果 - */ - @Multipart - @POST("detect") - suspend fun getRecognizeResult(@PartMap body: MutableMap): String - - /** * 获取知识库分类列表 */ @GET("/knowledge-class/list") diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt index beedfe1..4ab071e 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt @@ -11,7 +11,6 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File @@ -26,13 +25,6 @@ RetrofitFactory.createRetrofit(httpConfig, timeout = 20) } - private val aiApi by lazy { - val httpConfig = SaveKeyValues.getValue( - LocaleConstant.AI_SERVER_CONFIG, LocaleConstant.AI_BASE_URL - ) as String - RetrofitFactory.createRetrofit(httpConfig, timeout = 20) - } - private val gson by lazy { Gson() } private val typeToken = object : TypeToken>>() {}.type @@ -221,26 +213,6 @@ } /** - * 获取场景 - * */ - suspend fun getScene(base64: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - return aiApi.getScene(map) - } - - /** - * 获取画面识别结果 - * */ - suspend fun getRecognizeResult(base64: String, scene: String, inspectionId: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - map["scene"] = scene.toRequestBody() - map["xunjian_id"] = inspectionId.toRequestBody() - return aiApi.getRecognizeResult(map) - } - - /** * 获取知识库分类列表 */ suspend fun getLibraryList(): String { diff --git a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt index b4d468f..05ea8c7 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt @@ -33,112 +33,49 @@ ) } - val CLASS_NAMES_ARRAY = arrayListOf( - "三脚架", - "三通", - "专用软管", - "人", - "切断阀", - "危险告知牌", - "压力测试仪", - "压力表", - "反光衣", - "呼吸面罩", - "喉箍", - "四合一", - "圆头水枪", - "头", - "安全告知牌", - "安全帽", - "安全标识", - "安全绳", - "对讲设备", - "尖头水枪", - "工服", - "开关", - "报警装置", - "接头", - "施工路牌", - "气体检测报警仪", - "水带", - "水带_矩形", - "流量计", - "消火栓箱", - "灭火器", - "灶台", - "灶眼", - "照明设备", - "熄火保护", - "电线暴露", - "电路图", - "警戒线", - "调压器", - "调长器", - "贴纸", - "跨电线", - "路锥", - "过滤器", - "配电箱", - "长柄阀门", - "闪光灯亮", - "闪光灯灭", - "阀门", - "非专用软管", - "风管", - "鼓风机" + val TARGET_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "标准软管", "人", "切断阀", "危险告知牌", "压力表", + "压力表", "防护服", "呼气器", "喉箍", "气体检测报警仪", "水枪", "", + "安全告知牌", "安全帽", "安全警示标识", "安全绳", "对讲设备", "水枪", "工服", + "开关", "燃气探测器", "接头", "施工路牌", "气体检测报警仪", "水带", "水带", + "流量计", "消火栓箱", "灭火器", "灶台", "灶具", "照明设备", "熄火保护", + "电线裸露", "电路图", "警戒线", "调压器", "调长器", "贴纸", "跨电线", + "路锥", "过滤器", "配电箱外部", "长柄阀门", "", "", "阀门", + "非标准软管", "送风设备", "送风设备" ) - val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "腐蚀、铁锈", "龟裂") + val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "铁锈", "龟裂") - val HIDDEN_TROUBLE_ARRAY = arrayOf( - "配电箱无警示标识", - "配电箱内无电路图", - "配电箱内部电线裸露", - "配电箱有跨电线", - "未佩戴安全帽", - "未着工服", - "没有佩戴安全带、安全绳", - "未发现呼吸防护设备", - "未发现路锥、警戒线", - "未发现安全告知牌", - "未发现通风设备", - "未发现井下照明设备", - "未发现井下对讲设备", - "未发现施工三脚架", - "未发现气体检测仪", - "非专用软管", - "软管有接头或三通", - "未发现切断阀", - "未发现熄火保护装置", - "未发现燃气泄漏报警装置" - ) - - //配电箱 - val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( - "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" - ) - - //有限空间作业 - val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( - "安全帽", "呼吸面罩", "施工路牌", "安全告知牌", "危险告知牌", "警戒线", - "路锥", "三脚架", "对讲机", "反光衣", "照明设备", "气体检测仪", "安全绳", - "灭火器", "风管", "鼓风机", "人" - ) - - //非居 - val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( - "三通", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头", "灶台", - "灶眼", + //配电箱外部 + val P_D_X_SCENE_ARRAY = arrayListOf( + "配电箱外部", "配电箱内部", "安全警示标识", "开关", "开关标识", "电路图", "跨电线" ) //调压站 - val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( - "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + val T_Y_Z_SCENE_ARRAY = arrayListOf( + "调压器", "过滤器", "阀门", "压力表", "调长器", "流量计", "安全阀" ) //建筑消防 - val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( - "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形" + val J_Z_X_F_SCENE_ARRAY = arrayListOf( + "消火栓箱", "水枪", "水带", "消火栓", "灭火器" + ) + + //有限空间作业 + val Y_X_K_J_Z_Y_SCENE_ARRAY = arrayListOf( + "路锥", "警戒线", "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", "呼吸器", + "对讲设备", "照明设备", "气体检测报警仪", "工服", "防护服", "安全帽" + ) + + //非居 + val F_Z_M_SCENE_ARRAY = arrayListOf( + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", "燃气管道", "切断阀", + "阀门", "标准软管", "非标准软管" + ) + + //居民用户 + val Z_M_SCENE_ARRAY = arrayListOf( + "标准软管", "非标准软管", "灶具", "熄火保护" ) /** @@ -157,8 +94,5 @@ const val ACCOUNT = "account" const val PASSWORD = "password" const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" - const val BASE_IP = "111.198.10.15:22003" - const val SERVER_BASE_URL = "http://${BASE_IP}" - const val AI_SERVER_CONFIG = "aiServerConfig" - const val AI_BASE_URL = "http://192.168.206.248:5000" + const val SERVER_BASE_URL = "http://111.198.10.15:22003" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt new file mode 100644 index 0000000..26a7790 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt @@ -0,0 +1,232 @@ +package com.casic.br.ar.app.utils + +import com.casic.br.ar.app.extensions.isContains +import com.casic.br.ar.app.external.YoloResult +import com.casic.br.ar.app.model.HiddenTroubleResult + +class YoloTargetDetectHelper { + + private val kTag = "YoloTargetDetectHelper" + + @JvmField + @Volatile + var hiddenTroubles = ArrayList() + + fun siftHiddenTrouble( + segmentationResults: MutableList, detectResults: MutableList + ) { + //只有有限空间作业才筛选以下隐患 + when (RuntimeCache.sceneName) { + "有限空间作业" -> { + //结果包含人 + if (detectResults.isContains(3)) { + if (!detectResults.isContains(20) || !detectResults.isContains(8)) { + //不包含工服/防护服 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" + result.warning = "未穿工服/防护服" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(15)) { + //不包含安全帽 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" + result.warning = "未佩戴安全帽" + hiddenTroubles.add(result) + } + } + + //结果不包含呼吸防护设备 + if (!detectResults.isContains(9)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerMask" + result.warning = "现场无呼吸器" + hiddenTroubles.add(result) + } + + //结果不包含路锥、警戒线 + if (!detectResults.isContains(42) || !detectResults.isContains(37)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoEnclosure" + result.warning = "现场无围挡设施" + hiddenTroubles.add(result) + } + + //结果不包含安全告知牌 + if (!detectResults.isContains(14) || + !detectResults.isContains(5) || + !detectResults.isContains(24) + ) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWarningSign" + result.warning = "现场无安全告知牌" + hiddenTroubles.add(result) + } + + //TODO 新类型 + if (!detectResults.isContains(999999)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoJobInformationSign" + result.warning = "现场无作业信息公示牌" + hiddenTroubles.add(result) + } + + //结果不包含通风设备 + if (!detectResults.isContains(50) || !detectResults.isContains(51)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoAirSupply" + result.warning = "现场无送风设备" + hiddenTroubles.add(result) + } + + //结果不包含井下照明设备 + if (!detectResults.isContains(33)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoLighting" + result.warning = "现场无照明设备" + hiddenTroubles.add(result) + } + + //结果不包含对讲设备 + if (!detectResults.isContains(18)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoIntercom" + result.warning = "现场无对讲设备" + hiddenTroubles.add(result) + } + + //结果不包含施工三脚架 + if (!detectResults.isContains(0)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoTripod" + result.warning = "现场无三脚架" + hiddenTroubles.add(result) + } + + //结果不包含气体检测仪 + if (!detectResults.isContains(25)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoGasDetector" + result.warning = "现场无气体检测报警仪" + hiddenTroubles.add(result) + } + } + + "配电箱" -> { + //结果包含配电箱 + if (detectResults.isContains(44)) { + //且还包括开关 + if (detectResults.isContains(21)) { + if (!detectResults.isContains(36)) { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoCircuitDiagram" + result.warning = "配电箱内无电路图" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(35)) { + //包含电线裸露 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasExposedWire" + result.warning = "配电箱内部电线裸露" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(41)) { + //包含跨电线 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoJumperWire" + result.warning = "配电箱箱体和箱盖未跨接" + hiddenTroubles.add(result) + } + } else { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoWarningSign" + result.warning = "配电箱无警示标识" + hiddenTroubles.add(result) + } + } + } + + "非居用户" -> { + if (segmentationResults.isContains(4)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasPipelineRust" + result.warning = "管道腐蚀锈蚀" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(22)) { + //不包含燃气泄漏报警装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoAlarmDevice" + result.warning = "无燃气泄漏报警装置" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(4)) { + //不包含切断阀 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoShutoffValve" + result.warning = "未设置切断阀" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护装置" + hiddenTroubles.add(result) + } + } + } + + "居民用户" -> { + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护" + hiddenTroubles.add(result) + } + } + } + } + } +} \ No newline at end of file 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 8cf56a1..d40dd34 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 @@ -16,7 +16,6 @@ import com.casic.br.ar.app.extensions.convert2YoloResult import com.casic.br.ar.app.extensions.getSceneByTarget import com.casic.br.ar.app.extensions.getSceneCodeByName -import com.casic.br.ar.app.extensions.isInScene import com.casic.br.ar.app.external.INativeCallback import com.casic.br.ar.app.external.YoloResult import com.casic.br.ar.app.external.Yolov8ncnn @@ -56,7 +55,6 @@ private val kTag = "StartCheckActivity" private val context = this - private val targetSet by lazy { HashSet() } private val detectedSceneSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } private val mat by lazy { Mat() } @@ -71,9 +69,9 @@ private lateinit var hiddenTroubleViewModel: HiddenTroubleViewModel private lateinit var headItem: SceneCheckManifestModel.DataModel private lateinit var timer: Timer + private lateinit var troubleResult: HiddenTroubleResult private var checkItemLinkedList = LinkedList() private var isDetectTarget = false - private var alarmCode = "" private var checkItemCount = 0 private var checkPassCount = 0 private var troubleCount = 0 @@ -116,19 +114,27 @@ } configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(context, "pitfallBigType") + configViewModel.getDictionaryByCode(this, "pitfallBigType") configViewModel.dictionary.observe(this) { if (it.code == 200) { RuntimeCache.mainDicModels = it.data } } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.resultModel.observe(this) { + if (it == 200) { + "提交成功".show(this) + } + } + + imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] imageFileViewModel.resultModel.observe(this) { if (it.code == 200) { //添加此次检查发现的隐患 - alarmViewModel.uploadDetectTargetAlarm(context, alarmCode, it.data.toString()) + alarmViewModel.uploadDetectTargetAlarm( + this, troubleResult.alarmCode, it.data.toString() + ) troubleCount++ binding.troubleCountView.text = "${troubleCount}项" binding.noCheckCountView.text = "${checkItemLinkedList.size}项" @@ -155,7 +161,6 @@ override fun run() { runOnUiThread { if (!checkItemDialog.isShowing && checkItemLinkedList.isNotEmpty() && !addHiddenTroubleDialog.isShowing) { - //取出队列头部元素 headItem = checkItemLinkedList.poll()!! checkItemDialog.updateCheckItemView(headItem.checkItem, object : CheckItemDialog.OnDialogButtonClickListener { @@ -168,10 +173,13 @@ } } - override fun onHaveTroubleClick(file: File?) { + override fun onHaveTroubleClick( + file: File?, troubleResult: HiddenTroubleResult + ) { if (file == null) { showAddHiddenTroubleDialog() } else { + this@CheckModeActivity.troubleResult = troubleResult imageFileViewModel.uploadImage(file) } } @@ -280,6 +288,8 @@ lifecycleScope.launch(Dispatchers.Main) { yolov8ncnn.closeCamera() + timer.cancel() + delay(1000) finish() @@ -317,24 +327,9 @@ } binding.detectView.updateTargetPosition(segmentationResults, detectResults) - //筛选隐患获取alarmCode runOnUiThread { if (checkItemDialog.isShowing) { - checkItemDialog.updateTargetResults(segmentationResults, detectResults, mat, - object : CheckItemDialog.OnDetectCallback { - override fun onTroubleResult(result: HiddenTroubleResult) { - alarmCode = result.alarmCode - } - }) - } - } - - lifecycleScope.launch(Dispatchers.Main) { - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - } + checkItemDialog.updateTargetResults(segmentationResults, detectResults, mat) } } } @@ -344,12 +339,10 @@ return } - val firstYoloResult = output.first().toInt() //取结果的第一个为场景判断 - val label = LocaleConstant.CLASS_NAMES_ARRAY[firstYoloResult] + val label = LocaleConstant.TARGET_NAMES_ARRAY[output.first().toInt()] val scene = label.getSceneByTarget() - - if (scene == "未知场景") { + if (scene == "") { return } @@ -407,9 +400,4 @@ } return true } - - override fun onDestroy() { - super.onDestroy() - timer.cancel() - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt index 43db667..d0dece7 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt @@ -8,7 +8,6 @@ import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Part -import retrofit2.http.PartMap import retrofit2.http.Path import retrofit2.http.Query @@ -160,20 +159,6 @@ ): String /** - * 获取场景 - */ - @Multipart - @POST("/getScene") - suspend fun getScene(@PartMap body: MutableMap): String - - /** - * 获取画面识别结果 - */ - @Multipart - @POST("detect") - suspend fun getRecognizeResult(@PartMap body: MutableMap): String - - /** * 获取知识库分类列表 */ @GET("/knowledge-class/list") diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt index beedfe1..4ab071e 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt @@ -11,7 +11,6 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File @@ -26,13 +25,6 @@ RetrofitFactory.createRetrofit(httpConfig, timeout = 20) } - private val aiApi by lazy { - val httpConfig = SaveKeyValues.getValue( - LocaleConstant.AI_SERVER_CONFIG, LocaleConstant.AI_BASE_URL - ) as String - RetrofitFactory.createRetrofit(httpConfig, timeout = 20) - } - private val gson by lazy { Gson() } private val typeToken = object : TypeToken>>() {}.type @@ -221,26 +213,6 @@ } /** - * 获取场景 - * */ - suspend fun getScene(base64: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - return aiApi.getScene(map) - } - - /** - * 获取画面识别结果 - * */ - suspend fun getRecognizeResult(base64: String, scene: String, inspectionId: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - map["scene"] = scene.toRequestBody() - map["xunjian_id"] = inspectionId.toRequestBody() - return aiApi.getRecognizeResult(map) - } - - /** * 获取知识库分类列表 */ suspend fun getLibraryList(): String { diff --git a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt index b4d468f..05ea8c7 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt @@ -33,112 +33,49 @@ ) } - val CLASS_NAMES_ARRAY = arrayListOf( - "三脚架", - "三通", - "专用软管", - "人", - "切断阀", - "危险告知牌", - "压力测试仪", - "压力表", - "反光衣", - "呼吸面罩", - "喉箍", - "四合一", - "圆头水枪", - "头", - "安全告知牌", - "安全帽", - "安全标识", - "安全绳", - "对讲设备", - "尖头水枪", - "工服", - "开关", - "报警装置", - "接头", - "施工路牌", - "气体检测报警仪", - "水带", - "水带_矩形", - "流量计", - "消火栓箱", - "灭火器", - "灶台", - "灶眼", - "照明设备", - "熄火保护", - "电线暴露", - "电路图", - "警戒线", - "调压器", - "调长器", - "贴纸", - "跨电线", - "路锥", - "过滤器", - "配电箱", - "长柄阀门", - "闪光灯亮", - "闪光灯灭", - "阀门", - "非专用软管", - "风管", - "鼓风机" + val TARGET_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "标准软管", "人", "切断阀", "危险告知牌", "压力表", + "压力表", "防护服", "呼气器", "喉箍", "气体检测报警仪", "水枪", "", + "安全告知牌", "安全帽", "安全警示标识", "安全绳", "对讲设备", "水枪", "工服", + "开关", "燃气探测器", "接头", "施工路牌", "气体检测报警仪", "水带", "水带", + "流量计", "消火栓箱", "灭火器", "灶台", "灶具", "照明设备", "熄火保护", + "电线裸露", "电路图", "警戒线", "调压器", "调长器", "贴纸", "跨电线", + "路锥", "过滤器", "配电箱外部", "长柄阀门", "", "", "阀门", + "非标准软管", "送风设备", "送风设备" ) - val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "腐蚀、铁锈", "龟裂") + val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "铁锈", "龟裂") - val HIDDEN_TROUBLE_ARRAY = arrayOf( - "配电箱无警示标识", - "配电箱内无电路图", - "配电箱内部电线裸露", - "配电箱有跨电线", - "未佩戴安全帽", - "未着工服", - "没有佩戴安全带、安全绳", - "未发现呼吸防护设备", - "未发现路锥、警戒线", - "未发现安全告知牌", - "未发现通风设备", - "未发现井下照明设备", - "未发现井下对讲设备", - "未发现施工三脚架", - "未发现气体检测仪", - "非专用软管", - "软管有接头或三通", - "未发现切断阀", - "未发现熄火保护装置", - "未发现燃气泄漏报警装置" - ) - - //配电箱 - val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( - "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" - ) - - //有限空间作业 - val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( - "安全帽", "呼吸面罩", "施工路牌", "安全告知牌", "危险告知牌", "警戒线", - "路锥", "三脚架", "对讲机", "反光衣", "照明设备", "气体检测仪", "安全绳", - "灭火器", "风管", "鼓风机", "人" - ) - - //非居 - val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( - "三通", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头", "灶台", - "灶眼", + //配电箱外部 + val P_D_X_SCENE_ARRAY = arrayListOf( + "配电箱外部", "配电箱内部", "安全警示标识", "开关", "开关标识", "电路图", "跨电线" ) //调压站 - val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( - "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + val T_Y_Z_SCENE_ARRAY = arrayListOf( + "调压器", "过滤器", "阀门", "压力表", "调长器", "流量计", "安全阀" ) //建筑消防 - val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( - "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形" + val J_Z_X_F_SCENE_ARRAY = arrayListOf( + "消火栓箱", "水枪", "水带", "消火栓", "灭火器" + ) + + //有限空间作业 + val Y_X_K_J_Z_Y_SCENE_ARRAY = arrayListOf( + "路锥", "警戒线", "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", "呼吸器", + "对讲设备", "照明设备", "气体检测报警仪", "工服", "防护服", "安全帽" + ) + + //非居 + val F_Z_M_SCENE_ARRAY = arrayListOf( + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", "燃气管道", "切断阀", + "阀门", "标准软管", "非标准软管" + ) + + //居民用户 + val Z_M_SCENE_ARRAY = arrayListOf( + "标准软管", "非标准软管", "灶具", "熄火保护" ) /** @@ -157,8 +94,5 @@ const val ACCOUNT = "account" const val PASSWORD = "password" const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" - const val BASE_IP = "111.198.10.15:22003" - const val SERVER_BASE_URL = "http://${BASE_IP}" - const val AI_SERVER_CONFIG = "aiServerConfig" - const val AI_BASE_URL = "http://192.168.206.248:5000" + const val SERVER_BASE_URL = "http://111.198.10.15:22003" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt new file mode 100644 index 0000000..26a7790 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt @@ -0,0 +1,232 @@ +package com.casic.br.ar.app.utils + +import com.casic.br.ar.app.extensions.isContains +import com.casic.br.ar.app.external.YoloResult +import com.casic.br.ar.app.model.HiddenTroubleResult + +class YoloTargetDetectHelper { + + private val kTag = "YoloTargetDetectHelper" + + @JvmField + @Volatile + var hiddenTroubles = ArrayList() + + fun siftHiddenTrouble( + segmentationResults: MutableList, detectResults: MutableList + ) { + //只有有限空间作业才筛选以下隐患 + when (RuntimeCache.sceneName) { + "有限空间作业" -> { + //结果包含人 + if (detectResults.isContains(3)) { + if (!detectResults.isContains(20) || !detectResults.isContains(8)) { + //不包含工服/防护服 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" + result.warning = "未穿工服/防护服" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(15)) { + //不包含安全帽 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" + result.warning = "未佩戴安全帽" + hiddenTroubles.add(result) + } + } + + //结果不包含呼吸防护设备 + if (!detectResults.isContains(9)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerMask" + result.warning = "现场无呼吸器" + hiddenTroubles.add(result) + } + + //结果不包含路锥、警戒线 + if (!detectResults.isContains(42) || !detectResults.isContains(37)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoEnclosure" + result.warning = "现场无围挡设施" + hiddenTroubles.add(result) + } + + //结果不包含安全告知牌 + if (!detectResults.isContains(14) || + !detectResults.isContains(5) || + !detectResults.isContains(24) + ) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWarningSign" + result.warning = "现场无安全告知牌" + hiddenTroubles.add(result) + } + + //TODO 新类型 + if (!detectResults.isContains(999999)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoJobInformationSign" + result.warning = "现场无作业信息公示牌" + hiddenTroubles.add(result) + } + + //结果不包含通风设备 + if (!detectResults.isContains(50) || !detectResults.isContains(51)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoAirSupply" + result.warning = "现场无送风设备" + hiddenTroubles.add(result) + } + + //结果不包含井下照明设备 + if (!detectResults.isContains(33)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoLighting" + result.warning = "现场无照明设备" + hiddenTroubles.add(result) + } + + //结果不包含对讲设备 + if (!detectResults.isContains(18)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoIntercom" + result.warning = "现场无对讲设备" + hiddenTroubles.add(result) + } + + //结果不包含施工三脚架 + if (!detectResults.isContains(0)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoTripod" + result.warning = "现场无三脚架" + hiddenTroubles.add(result) + } + + //结果不包含气体检测仪 + if (!detectResults.isContains(25)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoGasDetector" + result.warning = "现场无气体检测报警仪" + hiddenTroubles.add(result) + } + } + + "配电箱" -> { + //结果包含配电箱 + if (detectResults.isContains(44)) { + //且还包括开关 + if (detectResults.isContains(21)) { + if (!detectResults.isContains(36)) { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoCircuitDiagram" + result.warning = "配电箱内无电路图" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(35)) { + //包含电线裸露 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasExposedWire" + result.warning = "配电箱内部电线裸露" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(41)) { + //包含跨电线 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoJumperWire" + result.warning = "配电箱箱体和箱盖未跨接" + hiddenTroubles.add(result) + } + } else { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoWarningSign" + result.warning = "配电箱无警示标识" + hiddenTroubles.add(result) + } + } + } + + "非居用户" -> { + if (segmentationResults.isContains(4)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasPipelineRust" + result.warning = "管道腐蚀锈蚀" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(22)) { + //不包含燃气泄漏报警装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoAlarmDevice" + result.warning = "无燃气泄漏报警装置" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(4)) { + //不包含切断阀 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoShutoffValve" + result.warning = "未设置切断阀" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护装置" + hiddenTroubles.add(result) + } + } + } + + "居民用户" -> { + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护" + hiddenTroubles.add(result) + } + } + } + } + } +} \ No newline at end of file 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 8cf56a1..d40dd34 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 @@ -16,7 +16,6 @@ import com.casic.br.ar.app.extensions.convert2YoloResult import com.casic.br.ar.app.extensions.getSceneByTarget import com.casic.br.ar.app.extensions.getSceneCodeByName -import com.casic.br.ar.app.extensions.isInScene import com.casic.br.ar.app.external.INativeCallback import com.casic.br.ar.app.external.YoloResult import com.casic.br.ar.app.external.Yolov8ncnn @@ -56,7 +55,6 @@ private val kTag = "StartCheckActivity" private val context = this - private val targetSet by lazy { HashSet() } private val detectedSceneSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } private val mat by lazy { Mat() } @@ -71,9 +69,9 @@ private lateinit var hiddenTroubleViewModel: HiddenTroubleViewModel private lateinit var headItem: SceneCheckManifestModel.DataModel private lateinit var timer: Timer + private lateinit var troubleResult: HiddenTroubleResult private var checkItemLinkedList = LinkedList() private var isDetectTarget = false - private var alarmCode = "" private var checkItemCount = 0 private var checkPassCount = 0 private var troubleCount = 0 @@ -116,19 +114,27 @@ } configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(context, "pitfallBigType") + configViewModel.getDictionaryByCode(this, "pitfallBigType") configViewModel.dictionary.observe(this) { if (it.code == 200) { RuntimeCache.mainDicModels = it.data } } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.resultModel.observe(this) { + if (it == 200) { + "提交成功".show(this) + } + } + + imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] imageFileViewModel.resultModel.observe(this) { if (it.code == 200) { //添加此次检查发现的隐患 - alarmViewModel.uploadDetectTargetAlarm(context, alarmCode, it.data.toString()) + alarmViewModel.uploadDetectTargetAlarm( + this, troubleResult.alarmCode, it.data.toString() + ) troubleCount++ binding.troubleCountView.text = "${troubleCount}项" binding.noCheckCountView.text = "${checkItemLinkedList.size}项" @@ -155,7 +161,6 @@ override fun run() { runOnUiThread { if (!checkItemDialog.isShowing && checkItemLinkedList.isNotEmpty() && !addHiddenTroubleDialog.isShowing) { - //取出队列头部元素 headItem = checkItemLinkedList.poll()!! checkItemDialog.updateCheckItemView(headItem.checkItem, object : CheckItemDialog.OnDialogButtonClickListener { @@ -168,10 +173,13 @@ } } - override fun onHaveTroubleClick(file: File?) { + override fun onHaveTroubleClick( + file: File?, troubleResult: HiddenTroubleResult + ) { if (file == null) { showAddHiddenTroubleDialog() } else { + this@CheckModeActivity.troubleResult = troubleResult imageFileViewModel.uploadImage(file) } } @@ -280,6 +288,8 @@ lifecycleScope.launch(Dispatchers.Main) { yolov8ncnn.closeCamera() + timer.cancel() + delay(1000) finish() @@ -317,24 +327,9 @@ } binding.detectView.updateTargetPosition(segmentationResults, detectResults) - //筛选隐患获取alarmCode runOnUiThread { if (checkItemDialog.isShowing) { - checkItemDialog.updateTargetResults(segmentationResults, detectResults, mat, - object : CheckItemDialog.OnDetectCallback { - override fun onTroubleResult(result: HiddenTroubleResult) { - alarmCode = result.alarmCode - } - }) - } - } - - lifecycleScope.launch(Dispatchers.Main) { - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - } + checkItemDialog.updateTargetResults(segmentationResults, detectResults, mat) } } } @@ -344,12 +339,10 @@ return } - val firstYoloResult = output.first().toInt() //取结果的第一个为场景判断 - val label = LocaleConstant.CLASS_NAMES_ARRAY[firstYoloResult] + val label = LocaleConstant.TARGET_NAMES_ARRAY[output.first().toInt()] val scene = label.getSceneByTarget() - - if (scene == "未知场景") { + if (scene == "") { return } @@ -407,9 +400,4 @@ } return true } - - override fun onDestroy() { - super.onDestroy() - timer.cancel() - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt index 564d13b..7639c2e 100644 --- a/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt @@ -1,6 +1,7 @@ package com.casic.br.ar.app.vm import android.content.Context +import androidx.lifecycle.MutableLiveData import com.casic.br.ar.app.extensions.getResponseCode import com.casic.br.ar.app.extensions.getResponseMessage import com.casic.br.ar.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) } diff --git a/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt new file mode 100644 index 0000000..12e2c94 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/callback/OnYoloResultSiftCallback.kt @@ -0,0 +1,7 @@ +package com.casic.br.ar.app.callback + +import com.casic.br.ar.app.model.HiddenTroubleResult + +interface OnYoloResultSiftCallback { + fun onResultSifted(results: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt index b0c55c9..c5602b1 100644 --- a/app/src/main/java/com/casic/br/ar/app/extensions/String.kt +++ b/app/src/main/java/com/casic/br/ar/app/extensions/String.kt @@ -42,20 +42,15 @@ } fun String.getSceneByTarget(): String { - val scene = if (LocaleConstant.DISTRIBUTION_BOX_SCENE_ARRAY.contains(this)) { - "配电箱" - } else if (LocaleConstant.PRESSURE_REGULATING_STATION_SCENE_ARRAY.contains(this)) { - "调压站" - } else if (LocaleConstant.FIRE_PROTECTION_SCENE_ARRAY.contains(this)) { - "建筑消防" - } else if (LocaleConstant.CONFINED_SPACES_SCENE_ARRAY.contains(this)) { - "有限空间作业" - } else if (LocaleConstant.NON_RESIDENTIAL_SCENE_ARRAY.contains(this)) { - "非居用户" - } else { - "未知场景" + when (this) { + in LocaleConstant.P_D_X_SCENE_ARRAY -> return "配电箱" + in LocaleConstant.T_Y_Z_SCENE_ARRAY -> return "调压站" + in LocaleConstant.J_Z_X_F_SCENE_ARRAY -> return "建筑消防" + in LocaleConstant.Y_X_K_J_Z_Y_SCENE_ARRAY -> return "有限空间作业" + in LocaleConstant.F_Z_M_SCENE_ARRAY -> return "非居用户" + in LocaleConstant.Z_M_SCENE_ARRAY -> return "居民用户" } - return scene + return "" } fun String.getSceneCodeByName(): String { @@ -67,44 +62,32 @@ return "" } -fun String.isInScene(scene: String): Boolean { - when (scene) { - "配电箱" -> return listOf("配电箱", "电路图", "开关/控制设备", "电线", "跨电线").contains( - this - ) - +fun String.isTargetInScene(): Boolean { + when (RuntimeCache.sceneName) { + "配电箱" -> return listOf("开关", "跨电线").contains(this) "有限空间作业" -> return listOf( - "安全帽", - "呼吸器", - "防护服", - "围挡设施", - "安全警示标识", - "送风设备", - "照明设备", - "对讲设备", - "三脚架", - "气体检测报警仪" + "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", + "呼吸器", "照明设备", "气体检测报警仪", "防护服", + "安全帽" ).contains(this) "非居民用户" -> return listOf( - "软管", - "接头", - "喉箍", - "切断阀", - "灶具", - "熄火保护", - "燃气泄漏报警装置" + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", + "燃气管道", "防爆灯", "切断阀", "排烟设施", + "阀门" ).contains(this) - "居民用户" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) + "居民用户" -> return listOf("软管", "灶具").contains(this) + "调压站" -> return listOf( + "调压器", + "过滤器", + "阀门", + "压力表", + "流量计", + "安全阀" + ).contains(this) - "调压站" -> return listOf("软管", "接头", "喉箍", "切断阀", "灶具", "熄火保护").contains( - this - ) - - "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "灭火器").contains(this) + "建筑消防" -> return listOf("消火栓箱", "水枪", "水带", "消火栓", "灭火器").contains(this) } return false } diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt index 43db667..d0dece7 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitService.kt @@ -8,7 +8,6 @@ import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Part -import retrofit2.http.PartMap import retrofit2.http.Path import retrofit2.http.Query @@ -160,20 +159,6 @@ ): String /** - * 获取场景 - */ - @Multipart - @POST("/getScene") - suspend fun getScene(@PartMap body: MutableMap): String - - /** - * 获取画面识别结果 - */ - @Multipart - @POST("detect") - suspend fun getRecognizeResult(@PartMap body: MutableMap): String - - /** * 获取知识库分类列表 */ @GET("/knowledge-class/list") diff --git a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt index beedfe1..4ab071e 100644 --- a/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ar/app/retrofit/RetrofitServiceManager.kt @@ -11,7 +11,6 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File @@ -26,13 +25,6 @@ RetrofitFactory.createRetrofit(httpConfig, timeout = 20) } - private val aiApi by lazy { - val httpConfig = SaveKeyValues.getValue( - LocaleConstant.AI_SERVER_CONFIG, LocaleConstant.AI_BASE_URL - ) as String - RetrofitFactory.createRetrofit(httpConfig, timeout = 20) - } - private val gson by lazy { Gson() } private val typeToken = object : TypeToken>>() {}.type @@ -221,26 +213,6 @@ } /** - * 获取场景 - * */ - suspend fun getScene(base64: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - return aiApi.getScene(map) - } - - /** - * 获取画面识别结果 - * */ - suspend fun getRecognizeResult(base64: String, scene: String, inspectionId: String): String { - val map: MutableMap = mutableMapOf() - map["img"] = "data:image/png;base64,${base64}".toRequestBody() - map["scene"] = scene.toRequestBody() - map["xunjian_id"] = inspectionId.toRequestBody() - return aiApi.getRecognizeResult(map) - } - - /** * 获取知识库分类列表 */ suspend fun getLibraryList(): String { diff --git a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt index b4d468f..05ea8c7 100644 --- a/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ar/app/utils/LocaleConstant.kt @@ -33,112 +33,49 @@ ) } - val CLASS_NAMES_ARRAY = arrayListOf( - "三脚架", - "三通", - "专用软管", - "人", - "切断阀", - "危险告知牌", - "压力测试仪", - "压力表", - "反光衣", - "呼吸面罩", - "喉箍", - "四合一", - "圆头水枪", - "头", - "安全告知牌", - "安全帽", - "安全标识", - "安全绳", - "对讲设备", - "尖头水枪", - "工服", - "开关", - "报警装置", - "接头", - "施工路牌", - "气体检测报警仪", - "水带", - "水带_矩形", - "流量计", - "消火栓箱", - "灭火器", - "灶台", - "灶眼", - "照明设备", - "熄火保护", - "电线暴露", - "电路图", - "警戒线", - "调压器", - "调长器", - "贴纸", - "跨电线", - "路锥", - "过滤器", - "配电箱", - "长柄阀门", - "闪光灯亮", - "闪光灯灭", - "阀门", - "非专用软管", - "风管", - "鼓风机" + val TARGET_NAMES_ARRAY = arrayListOf( + "三脚架", "三通", "标准软管", "人", "切断阀", "危险告知牌", "压力表", + "压力表", "防护服", "呼气器", "喉箍", "气体检测报警仪", "水枪", "", + "安全告知牌", "安全帽", "安全警示标识", "安全绳", "对讲设备", "水枪", "工服", + "开关", "燃气探测器", "接头", "施工路牌", "气体检测报警仪", "水带", "水带", + "流量计", "消火栓箱", "灭火器", "灶台", "灶具", "照明设备", "熄火保护", + "电线裸露", "电路图", "警戒线", "调压器", "调长器", "贴纸", "跨电线", + "路锥", "过滤器", "配电箱外部", "长柄阀门", "", "", "阀门", + "非标准软管", "送风设备", "送风设备" ) - val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "腐蚀、铁锈", "龟裂") + val SEGMENTATION_ARRAY = arrayOf("弯折", "断裂", "烧焦", "磨损", "铁锈", "龟裂") - val HIDDEN_TROUBLE_ARRAY = arrayOf( - "配电箱无警示标识", - "配电箱内无电路图", - "配电箱内部电线裸露", - "配电箱有跨电线", - "未佩戴安全帽", - "未着工服", - "没有佩戴安全带、安全绳", - "未发现呼吸防护设备", - "未发现路锥、警戒线", - "未发现安全告知牌", - "未发现通风设备", - "未发现井下照明设备", - "未发现井下对讲设备", - "未发现施工三脚架", - "未发现气体检测仪", - "非专用软管", - "软管有接头或三通", - "未发现切断阀", - "未发现熄火保护装置", - "未发现燃气泄漏报警装置" - ) - - //配电箱 - val DISTRIBUTION_BOX_SCENE_ARRAY = arrayListOf( - "安全标识", "电路图", "电线暴露", "跨电线", "配电箱", "贴纸", "开关" - ) - - //有限空间作业 - val CONFINED_SPACES_SCENE_ARRAY = arrayListOf( - "安全帽", "呼吸面罩", "施工路牌", "安全告知牌", "危险告知牌", "警戒线", - "路锥", "三脚架", "对讲机", "反光衣", "照明设备", "气体检测仪", "安全绳", - "灭火器", "风管", "鼓风机", "人" - ) - - //非居 - val NON_RESIDENTIAL_SCENE_ARRAY = arrayListOf( - "三通", "切断阀", "喉箍", "熄火保护", "风管", "软管", "报警装置", "接头", "灶台", - "灶眼", + //配电箱外部 + val P_D_X_SCENE_ARRAY = arrayListOf( + "配电箱外部", "配电箱内部", "安全警示标识", "开关", "开关标识", "电路图", "跨电线" ) //调压站 - val PRESSURE_REGULATING_STATION_SCENE_ARRAY = arrayListOf( - "调压器", "阀门", "压力表", "流量计", "过滤器", "调长器", "压力测试仪", "长柄阀门" + val T_Y_Z_SCENE_ARRAY = arrayListOf( + "调压器", "过滤器", "阀门", "压力表", "调长器", "流量计", "安全阀" ) //建筑消防 - val FIRE_PROTECTION_SCENE_ARRAY = arrayListOf( - "消火栓箱", "尖头水枪", "圆头水枪", "水带", "水带_矩形" + val J_Z_X_F_SCENE_ARRAY = arrayListOf( + "消火栓箱", "水枪", "水带", "消火栓", "灭火器" + ) + + //有限空间作业 + val Y_X_K_J_Z_Y_SCENE_ARRAY = arrayListOf( + "路锥", "警戒线", "安全告知牌", "作业信息公示牌", "三脚架", "送风设备", "呼吸器", + "对讲设备", "照明设备", "气体检测报警仪", "工服", "防护服", "安全帽" + ) + + //非居 + val F_Z_M_SCENE_ARRAY = arrayListOf( + "燃气计量器具", "可燃气体报警控制器", "燃气探测器", "燃气管道", "切断阀", + "阀门", "标准软管", "非标准软管" + ) + + //居民用户 + val Z_M_SCENE_ARRAY = arrayListOf( + "标准软管", "非标准软管", "灶具", "熄火保护" ) /** @@ -157,8 +94,5 @@ const val ACCOUNT = "account" const val PASSWORD = "password" const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" - const val BASE_IP = "111.198.10.15:22003" - const val SERVER_BASE_URL = "http://${BASE_IP}" - const val AI_SERVER_CONFIG = "aiServerConfig" - const val AI_BASE_URL = "http://192.168.206.248:5000" + const val SERVER_BASE_URL = "http://111.198.10.15:22003" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt new file mode 100644 index 0000000..26a7790 --- /dev/null +++ b/app/src/main/java/com/casic/br/ar/app/utils/YoloTargetDetectHelper.kt @@ -0,0 +1,232 @@ +package com.casic.br.ar.app.utils + +import com.casic.br.ar.app.extensions.isContains +import com.casic.br.ar.app.external.YoloResult +import com.casic.br.ar.app.model.HiddenTroubleResult + +class YoloTargetDetectHelper { + + private val kTag = "YoloTargetDetectHelper" + + @JvmField + @Volatile + var hiddenTroubles = ArrayList() + + fun siftHiddenTrouble( + segmentationResults: MutableList, detectResults: MutableList + ) { + //只有有限空间作业才筛选以下隐患 + when (RuntimeCache.sceneName) { + "有限空间作业" -> { + //结果包含人 + if (detectResults.isContains(3)) { + if (!detectResults.isContains(20) || !detectResults.isContains(8)) { + //不包含工服/防护服 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" + result.warning = "未穿工服/防护服" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(15)) { + //不包含安全帽 + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" + result.warning = "未佩戴安全帽" + hiddenTroubles.add(result) + } + } + + //结果不包含呼吸防护设备 + if (!detectResults.isContains(9)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWorkerMask" + result.warning = "现场无呼吸器" + hiddenTroubles.add(result) + } + + //结果不包含路锥、警戒线 + if (!detectResults.isContains(42) || !detectResults.isContains(37)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoEnclosure" + result.warning = "现场无围挡设施" + hiddenTroubles.add(result) + } + + //结果不包含安全告知牌 + if (!detectResults.isContains(14) || + !detectResults.isContains(5) || + !detectResults.isContains(24) + ) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoWarningSign" + result.warning = "现场无安全告知牌" + hiddenTroubles.add(result) + } + + //TODO 新类型 + if (!detectResults.isContains(999999)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoJobInformationSign" + result.warning = "现场无作业信息公示牌" + hiddenTroubles.add(result) + } + + //结果不包含通风设备 + if (!detectResults.isContains(50) || !detectResults.isContains(51)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoAirSupply" + result.warning = "现场无送风设备" + hiddenTroubles.add(result) + } + + //结果不包含井下照明设备 + if (!detectResults.isContains(33)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoLighting" + result.warning = "现场无照明设备" + hiddenTroubles.add(result) + } + + //结果不包含对讲设备 + if (!detectResults.isContains(18)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoIntercom" + result.warning = "现场无对讲设备" + hiddenTroubles.add(result) + } + + //结果不包含施工三脚架 + if (!detectResults.isContains(0)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoTripod" + result.warning = "现场无三脚架" + hiddenTroubles.add(result) + } + + //结果不包含气体检测仪 + if (!detectResults.isContains(25)) { + val result = HiddenTroubleResult() + result.alarmCode = "ConfinedSpaceHasNoGasDetector" + result.warning = "现场无气体检测报警仪" + hiddenTroubles.add(result) + } + } + + "配电箱" -> { + //结果包含配电箱 + if (detectResults.isContains(44)) { + //且还包括开关 + if (detectResults.isContains(21)) { + if (!detectResults.isContains(36)) { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoCircuitDiagram" + result.warning = "配电箱内无电路图" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(35)) { + //包含电线裸露 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasExposedWire" + result.warning = "配电箱内部电线裸露" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(41)) { + //包含跨电线 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoJumperWire" + result.warning = "配电箱箱体和箱盖未跨接" + hiddenTroubles.add(result) + } + } else { + //不包含警示标识 + val result = HiddenTroubleResult() + result.alarmCode = "DistributionBoxHasNoWarningSign" + result.warning = "配电箱无警示标识" + hiddenTroubles.add(result) + } + } + } + + "非居用户" -> { + if (segmentationResults.isContains(4)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasPipelineRust" + result.warning = "管道腐蚀锈蚀" + hiddenTroubles.add(result) + } + + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(22)) { + //不包含燃气泄漏报警装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoAlarmDevice" + result.warning = "无燃气泄漏报警装置" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(4)) { + //不包含切断阀 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoShutoffValve" + result.warning = "未设置切断阀" + hiddenTroubles.add(result) + } + + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护装置" + hiddenTroubles.add(result) + } + } + } + + "居民用户" -> { + if (detectResults.isContains(49)) { + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNonDedicatedHose" + result.warning = "非标准软管" + hiddenTroubles.add(result) + } + + if (segmentationResults.isContains(5)) { + val result = HiddenTroubleResult() + result.alarmCode = "HoseCrackedAndAged" + result.warning = "软管龟裂老化" + hiddenTroubles.add(result) + } + + //结果包含灶台、灶眼 + if (detectResults.isContains(31) || detectResults.isContains(32)) { + if (!detectResults.isContains(34)) { + //不包含熄火保护装置 + val result = HiddenTroubleResult() + result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" + result.warning = "未发现熄火保护" + hiddenTroubles.add(result) + } + } + } + } + } +} \ No newline at end of file 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 8cf56a1..d40dd34 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 @@ -16,7 +16,6 @@ import com.casic.br.ar.app.extensions.convert2YoloResult import com.casic.br.ar.app.extensions.getSceneByTarget import com.casic.br.ar.app.extensions.getSceneCodeByName -import com.casic.br.ar.app.extensions.isInScene import com.casic.br.ar.app.external.INativeCallback import com.casic.br.ar.app.external.YoloResult import com.casic.br.ar.app.external.Yolov8ncnn @@ -56,7 +55,6 @@ private val kTag = "StartCheckActivity" private val context = this - private val targetSet by lazy { HashSet() } private val detectedSceneSet by lazy { HashSet() } private val yolov8ncnn by lazy { Yolov8ncnn() } private val mat by lazy { Mat() } @@ -71,9 +69,9 @@ private lateinit var hiddenTroubleViewModel: HiddenTroubleViewModel private lateinit var headItem: SceneCheckManifestModel.DataModel private lateinit var timer: Timer + private lateinit var troubleResult: HiddenTroubleResult private var checkItemLinkedList = LinkedList() private var isDetectTarget = false - private var alarmCode = "" private var checkItemCount = 0 private var checkPassCount = 0 private var troubleCount = 0 @@ -116,19 +114,27 @@ } configViewModel = ViewModelProvider(this)[ConfigViewModel::class.java] - configViewModel.getDictionaryByCode(context, "pitfallBigType") + configViewModel.getDictionaryByCode(this, "pitfallBigType") configViewModel.dictionary.observe(this) { if (it.code == 200) { RuntimeCache.mainDicModels = it.data } } - imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.resultModel.observe(this) { + if (it == 200) { + "提交成功".show(this) + } + } + + imageFileViewModel = ViewModelProvider(this)[ImageFileViewModel::class.java] imageFileViewModel.resultModel.observe(this) { if (it.code == 200) { //添加此次检查发现的隐患 - alarmViewModel.uploadDetectTargetAlarm(context, alarmCode, it.data.toString()) + alarmViewModel.uploadDetectTargetAlarm( + this, troubleResult.alarmCode, it.data.toString() + ) troubleCount++ binding.troubleCountView.text = "${troubleCount}项" binding.noCheckCountView.text = "${checkItemLinkedList.size}项" @@ -155,7 +161,6 @@ override fun run() { runOnUiThread { if (!checkItemDialog.isShowing && checkItemLinkedList.isNotEmpty() && !addHiddenTroubleDialog.isShowing) { - //取出队列头部元素 headItem = checkItemLinkedList.poll()!! checkItemDialog.updateCheckItemView(headItem.checkItem, object : CheckItemDialog.OnDialogButtonClickListener { @@ -168,10 +173,13 @@ } } - override fun onHaveTroubleClick(file: File?) { + override fun onHaveTroubleClick( + file: File?, troubleResult: HiddenTroubleResult + ) { if (file == null) { showAddHiddenTroubleDialog() } else { + this@CheckModeActivity.troubleResult = troubleResult imageFileViewModel.uploadImage(file) } } @@ -280,6 +288,8 @@ lifecycleScope.launch(Dispatchers.Main) { yolov8ncnn.closeCamera() + timer.cancel() + delay(1000) finish() @@ -317,24 +327,9 @@ } binding.detectView.updateTargetPosition(segmentationResults, detectResults) - //筛选隐患获取alarmCode runOnUiThread { if (checkItemDialog.isShowing) { - checkItemDialog.updateTargetResults(segmentationResults, detectResults, mat, - object : CheckItemDialog.OnDetectCallback { - override fun onTroubleResult(result: HiddenTroubleResult) { - alarmCode = result.alarmCode - } - }) - } - } - - lifecycleScope.launch(Dispatchers.Main) { - detectResults.forEach { - val label = LocaleConstant.CLASS_NAMES_ARRAY[it.type] - if (label.isInScene(RuntimeCache.sceneName)) { - targetSet.add(label) - } + checkItemDialog.updateTargetResults(segmentationResults, detectResults, mat) } } } @@ -344,12 +339,10 @@ return } - val firstYoloResult = output.first().toInt() //取结果的第一个为场景判断 - val label = LocaleConstant.CLASS_NAMES_ARRAY[firstYoloResult] + val label = LocaleConstant.TARGET_NAMES_ARRAY[output.first().toInt()] val scene = label.getSceneByTarget() - - if (scene == "未知场景") { + if (scene == "") { return } @@ -407,9 +400,4 @@ } return true } - - override fun onDestroy() { - super.onDestroy() - timer.cancel() - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt index 564d13b..7639c2e 100644 --- a/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/ar/app/vm/AlarmViewModel.kt @@ -1,6 +1,7 @@ package com.casic.br.ar.app.vm import android.content.Context +import androidx.lifecycle.MutableLiveData import com.casic.br.ar.app.extensions.getResponseCode import com.casic.br.ar.app.extensions.getResponseMessage import com.casic.br.ar.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) } diff --git a/app/src/main/java/com/casic/br/ar/app/widgets/CheckItemDialog.kt b/app/src/main/java/com/casic/br/ar/app/widgets/CheckItemDialog.kt index 9589042..3f8df5c 100644 --- a/app/src/main/java/com/casic/br/ar/app/widgets/CheckItemDialog.kt +++ b/app/src/main/java/com/casic/br/ar/app/widgets/CheckItemDialog.kt @@ -8,7 +8,6 @@ import android.os.CountDownTimer import android.os.Handler import android.os.Message -import android.util.Log import com.casic.br.ar.app.R import com.casic.br.ar.app.callback.OnImageCompressListener import com.casic.br.ar.app.databinding.DialogCheckItemBinding @@ -17,16 +16,15 @@ import com.casic.br.ar.app.external.YoloResult import com.casic.br.ar.app.model.HiddenTroubleResult import com.casic.br.ar.app.utils.LocaleConstant +import com.casic.br.ar.app.utils.YoloTargetDetectHelper 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.saveImage -import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.WeakReferenceHandler import org.opencv.android.Utils import org.opencv.core.Mat import java.io.File -import java.util.Stack import java.util.Timer import java.util.TimerTask @@ -37,10 +35,11 @@ private val weakReferenceHandler by lazy { WeakReferenceHandler(this) } private val detectedTargetSet by lazy { HashSet() } private val timer by lazy { Timer() } - private var checkResultStack = Stack>() + private val detectHelper by lazy { YoloTargetDetectHelper() } private lateinit var checkItem: String private lateinit var mat: Mat private lateinit var listener: OnDialogButtonClickListener + private lateinit var hiddenTroubleResult: HiddenTroubleResult override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -52,7 +51,7 @@ } binding.haveTroubleButton.setOnClickListener { - listener.onHaveTroubleClick(null) + listener.onHaveTroubleClick(null, hiddenTroubleResult) dismiss() } } @@ -86,210 +85,21 @@ binding.haveTroubleButton.typeface = Typeface.defaultFromStyle(Typeface.NORMAL) binding.haveTroubleButton.setBackgroundResource(R.drawable.button_dialog_selector_red_25) - //每1s查一次缓存数据 + //每4s查一次缓存数据 timer.schedule(object : TimerTask() { override fun run() { weakReferenceHandler.sendEmptyMessage(2024092403) } - }, 0, 1000) + }, 0, 4000) return this } fun updateTargetResults( segmentationResults: MutableList, detectResults: MutableList, - mat: Mat, callback: OnDetectCallback + mat: Mat ) { this.mat = mat - for (it in detectResults) { - if (it.type == 44) { - //it此时代表配电箱 - if (!detectResults.isContains(16)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "DistributionBoxHasNoWarningSign" - result.warning = "配电箱无警示标识" - callback.onTroubleResult(result) - break - } else { - //配电箱内。有开关说明在内部 - if (detectResults.isContains(21)) { - if (!detectResults.isContains(36)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "DistributionBoxHasNoCircuitDiagram" - result.warning = "配电箱内无电路图" - callback.onTroubleResult(result) - break - } else if (detectResults.isContains(35)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "" - result.warning = "配电箱内部电线裸露" - callback.onTroubleResult(result) - break - } else if (detectResults.isContains(41)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "DistributionBoxHasNoJumperWire" - result.warning = "配电箱有跨电线" - callback.onTroubleResult(result) - break - } - } - } - } else if (it.type == 13) { - //it此时代表头 - if (!detectResults.isContains(15)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyHat" - result.warning = "未佩戴安全帽" - callback.onTroubleResult(result) - break - } - } else if (it.type == 3) { - //it此时代表人 - if (!detectResults.isContains(20)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoWorkerClothes" - result.warning = "未着工服" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(17)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoWorkerSafelyLine" - result.warning = "没有佩戴安全带、安全绳" - callback.onTroubleResult(result) - break - } - } else if (it.type == 31 || it.type == 32) { - //it此时代表灶台、灶眼 - if (!detectResults.isContains(34)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "" - result.warning = "未发现熄火保护装置" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(22)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "NonResidentUserHasNoStoveFlameoutProtection" - result.warning = "未发现燃气泄漏报警装置" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(4)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "NonResidentUserHasNoShutoffValve" - result.warning = "未发现切断阀" - callback.onTroubleResult(result) - break - } - } else if (it.type == 2 || it.type == 49) { - //it此时代表软管 - if (detectResults.isContains(1)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "NonResidentUserHasNoHoseJoint" - result.warning = "软管有接头或三通" - callback.onTroubleResult(result) - break - } - } else if (it.type == 9 || it.type == 42 || it.type == 37 || it.type == 14 || it.type == 50 || it.type == 51 || it.type == 33 || it.type == 18 || it.type == 0 || it.type == 25) { - if (!detectResults.isContains(9)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoWorkerMask" - result.warning = "未发现呼吸防护设备" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(42) || !detectResults.isContains(37)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoEnclosure" - result.warning = "未发现路锥、警戒线" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(14)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoWarningSign" - result.warning = "未发现安全告知牌" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(50) || !detectResults.isContains(51)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoAirSupply" - result.warning = "未发现通风设备" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(33)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoLighting" - result.warning = "未发现井下照明设备" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(18)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoIntercom" - result.warning = "未发现井下对讲设备" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(0)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoTripod" - result.warning = "未发现施工三脚架" - callback.onTroubleResult(result) - break - } else if (!detectResults.isContains(25)) { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "ConfinedSpaceHasNoGasDetector" - result.warning = "未发现气体检测仪" - callback.onTroubleResult(result) - break - } - } - } - - for (it in segmentationResults) { - when (it.type) { - 4 -> { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "NonResidentUserHasPipelineRust" - result.warning = "腐蚀、锈蚀" - callback.onTroubleResult(result) - break - } - - 0 -> { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "NonResidentUserHasHoseFlexure" - result.warning = "软管不可恢复的弯折拉伸" - callback.onTroubleResult(result) - break - } - - else -> { - val result = HiddenTroubleResult() - result.position = it.position - result.alarmCode = "" - result.warning = LocaleConstant.SEGMENTATION_ARRAY[it.type] - break - } - } - } - - checkResultStack.push(detectResults) + detectHelper.siftHiddenTrouble(segmentationResults, detectResults) } override fun handleMessage(msg: Message): Boolean { @@ -307,39 +117,11 @@ } 2024092403 -> { - if (checkResultStack.isEmpty()) { - return true - } - val detectResults = checkResultStack.pop() - //隐患筛选 - if (checkItem.contains("安全帽")) { - if (detectResults.isContains(13) && !detectResults.isContains(15)) { - //未佩戴安全帽 - startCountDownTimer("未佩戴安全帽", true) - return true - } - } - - if (checkItem.contains("防护服") || checkItem.contains("工服")) { - if (detectResults.isContains(13) && !detectResults.isContains(20)) { - //未着工服 - startCountDownTimer("未着工服", true) - return true - } - } - - if (checkItem.contains("安全带") || checkItem.contains("安全绳")) { - if (detectResults.isContains(13) && !detectResults.isContains(17)) { - startCountDownTimer("没有佩戴安全带、安全绳", true) - return true - } - } - - for (result in detectResults) { - val typeName = LocaleConstant.CLASS_NAMES_ARRAY[result.type] - if (checkItem.contains(typeName) || checkItem.contains("对讲设备")) { - startCountDownTimer(typeName, false) - return true + val lastResult = detectHelper.hiddenTroubles + for (res in lastResult) { + if (!detectedTargetSet.contains(res.warning)) { + handleWarningByCheckItem(lastResult, res) + break } } } @@ -347,12 +129,46 @@ return true } + private fun handleWarningByCheckItem( + lastResult: List, hiddenTroubleResult: HiddenTroubleResult + ) { + if (checkItem.contains("安全帽")) { + if (lastResult.isContains(13) && !lastResult.isContains(15)) { + this.hiddenTroubleResult = hiddenTroubleResult + //未佩戴安全帽 + startCountDownTimer("未佩戴安全帽", true) + return + } + } + + if (checkItem.contains("防护服") || checkItem.contains("工服")) { + if (lastResult.isContains(13) && !lastResult.isContains(20)) { + this.hiddenTroubleResult = hiddenTroubleResult + //未着工服 + startCountDownTimer("未着工服", true) + return + } + } + + if (checkItem.contains("安全带") || checkItem.contains("安全绳")) { + if (lastResult.isContains(13) && !lastResult.isContains(17)) { + this.hiddenTroubleResult = hiddenTroubleResult + startCountDownTimer("没有佩戴安全带、安全绳", true) + return + } + } + + for (result in lastResult) { + val typeName = LocaleConstant.TARGET_NAMES_ARRAY[result.type] + if (checkItem.contains(typeName) || checkItem.contains("对讲设备")) { + startCountDownTimer(typeName, false) + return + } + } + } + private var isCountDownCompleted = true private fun startCountDownTimer(typeName: String, saveImage: Boolean) { - if (detectedTargetSet.contains(typeName)) { - Log.d(kTag, detectedTargetSet.toJson()) - return - } if (isCountDownCompleted) { isCountDownCompleted = false object : CountDownTimer(3000, 1000) { @@ -374,11 +190,11 @@ if (saveImage) { val imagePath = mat2Image() if (imagePath == null) { - listener.onHaveTroubleClick(null) + listener.onHaveTroubleClick(null, hiddenTroubleResult) } else { imagePath.compressImage(context, object : OnImageCompressListener { override fun onSuccess(file: File) { - listener.onHaveTroubleClick(file) + listener.onHaveTroubleClick(file, hiddenTroubleResult) } override fun onError(e: Throwable) { @@ -399,10 +215,6 @@ interface OnDialogButtonClickListener { fun onCheckPassClick() - fun onHaveTroubleClick(file: File?) - } - - interface OnDetectCallback { - fun onTroubleResult(result: HiddenTroubleResult) + fun onHaveTroubleClick(file: File?, troubleResult: HiddenTroubleResult) } } \ No newline at end of file