采集向量优化调试
This commit is contained in:
@@ -25,8 +25,10 @@ import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import com.sw.dualscreen.GlobalData
|
||||
import com.sw.dualscreen.GlobalKey
|
||||
import com.sw.dualscreen.activity.fragment.CollectFragment
|
||||
import com.sw.dualscreen.adapter.SearchFoodAdapter
|
||||
import com.sw.dualscreen.databinding.ActivityMainBinding
|
||||
import com.sw.dualscreen.dialog.RemindDialog
|
||||
import com.sw.dualscreen.ext.dp
|
||||
import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.load
|
||||
@@ -36,12 +38,16 @@ import com.sw.dualscreen.model.response.ClickBackEvent
|
||||
import com.sw.dualscreen.model.response.FoodInfo
|
||||
import com.sw.dualscreen.model.response.FoodOrder
|
||||
import com.sw.dualscreen.model.response.PaySuccessEvent
|
||||
import com.sw.dualscreen.model.response.ResetBoxEvent
|
||||
import com.sw.dualscreen.model.response.UserFaceModel
|
||||
import com.sw.dualscreen.objbox.Food
|
||||
import com.sw.dualscreen.objbox.FoodModule
|
||||
import com.sw.dualscreen.objbox.FoodModule.IdNameScore
|
||||
import com.sw.dualscreen.objbox.ObjectBox
|
||||
import com.sw.dualscreen.presentation.MainScreenPresentation
|
||||
import com.sw.dualscreen.sdk.SensorScaleUtils
|
||||
import com.sw.dualscreen.socket.TcpClient
|
||||
import com.sw.dualscreen.utils.ActivityManager
|
||||
import com.sw.dualscreen.utils.BitmapSaver
|
||||
import com.sw.dualscreen.utils.Debouncer
|
||||
import com.sw.dualscreen.utils.GsonUtils
|
||||
@@ -58,7 +64,12 @@ import com.sw.plate.utils.ToastUtils
|
||||
import com.sw.plate.utils.arcface.facedb.FaceDatabase
|
||||
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
|
||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.kotlin.boxFor
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.json.JSONObject
|
||||
@@ -69,6 +80,7 @@ import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.collections.get
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@@ -135,6 +147,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
override fun initialize() {
|
||||
super.initialize()
|
||||
box = ObjectBox.boxStore.boxFor(Food::class)
|
||||
isPageVisible = true
|
||||
addBackEventListener()
|
||||
//FoodModule.init(this)
|
||||
@@ -262,7 +275,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.previewView.visibility = View.VISIBLE
|
||||
binding.ivImg.visibility = View.GONE
|
||||
resumeAnalysis()
|
||||
viewModel.cleanIdentifiedFoodInfoList()
|
||||
// viewModel.cleanIdentifiedFoodInfoList()
|
||||
return
|
||||
}
|
||||
pauseAnalysis()
|
||||
@@ -318,6 +331,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
SensorScaleUtils.addWeightListener { weight ->
|
||||
Timber.d("registerDataChange weight = $weight")
|
||||
if (isPageVisible.not() || isStartRecognize.not()) {
|
||||
if (ActivityManager.currentActivity() is MainActivity) {
|
||||
isPageVisible = true
|
||||
}
|
||||
return@addWeightListener
|
||||
}
|
||||
val isWeightChange = weight - lastWeight > 0.05
|
||||
@@ -328,8 +344,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
private fun recognizeByWeight(weight: Double, isWeightChange: Boolean, block: () -> Unit = {}) {
|
||||
presentation?.updateWeight(weight)
|
||||
|
||||
if (weight <= 0.005) {//余量取餐,检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
|
||||
if (weight <= 0.005) {
|
||||
////余量取餐,检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
|
||||
isRecognitionFood = true
|
||||
return
|
||||
}
|
||||
|
||||
if (isWeightChange && isRecognitionFood) { // 大于50g
|
||||
@@ -368,7 +386,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
failCount++
|
||||
hideWaitingDialog()
|
||||
// ToastUtils.showToast("拍照异常,请手动放置后重新识别")
|
||||
|
||||
shutdownCamera()
|
||||
setupCamera()
|
||||
@@ -389,39 +406,42 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
val queryData = GsonUtils.toJson(list)
|
||||
val recData = GsonUtils.toJson(scoreList)
|
||||
Timber.d("registerDataChange识别后查询接口数据:$queryData,识别数据:$recData")
|
||||
if (list.isEmpty()) {
|
||||
binding.tvToSearch.let {
|
||||
it.text = "未查询到,手动搜索"
|
||||
it.visible()
|
||||
}
|
||||
return
|
||||
}
|
||||
list.forEach { foodInfo ->
|
||||
val scoreItem = scoreList.firstOrNull { it.name == foodInfo.foodName }
|
||||
val score = scoreItem?.score ?: 0.0
|
||||
foodInfo.score = ((1 - score) * 10000).roundToInt()
|
||||
}
|
||||
val list2 = try {
|
||||
val orderList = scoreList.map { it.name.trim() }
|
||||
list.sortedBy { orderList.indexOf(it.foodName) }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
list
|
||||
}
|
||||
//接口已处理排序
|
||||
// val list2 = try {
|
||||
// val orderList = scoreList.map { it.name.trim() }
|
||||
// list.sortedBy { orderList.indexOf(it.foodName) }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// list
|
||||
// }
|
||||
searchFoodList.clear()
|
||||
searchFoodList.addAll(list2)
|
||||
searchFoodList.addAll(list)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.updateData(list)
|
||||
if (list2.isNotEmpty()) {
|
||||
checkedItem = list2[0]
|
||||
checkedItem!!.photoUri = lastPhotoUri
|
||||
checkedItem!!.isChecked = true
|
||||
adapter.notifyItemChanged(0)
|
||||
updateCurrentFood(checkedItem)
|
||||
lastPhotoUri = null
|
||||
LightManager.closeRedLight()
|
||||
|
||||
binding.flPay.visible()
|
||||
binding.tvToSearch.let {
|
||||
it.text = "以上都不是,手动搜索"
|
||||
it.visible()
|
||||
}
|
||||
} else {
|
||||
binding.flPay.gone()
|
||||
binding.tvToSearch.gone()
|
||||
checkedItem = list[0].also {
|
||||
it.photoUri = lastPhotoUri
|
||||
it.isChecked = true
|
||||
}
|
||||
adapter.notifyItemChanged(0)
|
||||
updateCurrentFood(checkedItem)
|
||||
// lastPhotoUri = null
|
||||
LightManager.closeRedLight()
|
||||
|
||||
binding.tvToSearch.let {
|
||||
it.text = "以上都不是,手动搜索"
|
||||
it.visible()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,14 +673,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.tvTitleTime.text = dateTime
|
||||
}
|
||||
|
||||
private var isPageVisible = true
|
||||
public var isPageVisible = true
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
isPageVisible = true
|
||||
// 启动定时器
|
||||
handler.postDelayed(timeoutRunnable, TIME_OUT)
|
||||
|
||||
// ToastUtils.showToast("isPageVisible=$isPageVisible")
|
||||
if (isFirstOpen) {
|
||||
//首次
|
||||
setupSecondaryDisplay()
|
||||
@@ -778,6 +798,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
foodOrderId = orderId
|
||||
block()
|
||||
|
||||
if (checkedItem!!.isFromSearch == true) {
|
||||
//当前菜名为手动搜索选择,非识别结果,保存向量数据
|
||||
saveFoodVector(checkedItem!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -886,6 +911,111 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将uri转为文件和向量数据并提交
|
||||
*/
|
||||
private fun saveFoodVector(foodInfo: FoodInfo) {
|
||||
try {
|
||||
lastPhotoUri?.let { uri ->
|
||||
uri2File(uri) { imageFile, imageVector ->
|
||||
runBlocking {
|
||||
uploadCollectFoodPics(foodInfo, imageFile, imageVector)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传菜品信息
|
||||
*/
|
||||
private suspend fun uploadCollectFoodPics(
|
||||
foodInfo: FoodInfo,
|
||||
imageFile: File?,
|
||||
imageVector: FloatArray?
|
||||
) {
|
||||
if (imageFile == null || imageVector == null) {
|
||||
Timber.tag(TAG)
|
||||
.d("是否null判断,imageFile == null:${imageFile == null},imageVector == null:${imageVector == null}")
|
||||
return
|
||||
}
|
||||
val foodId = foodInfo.foodId
|
||||
val foodName = foodInfo.foodName ?: ""
|
||||
val foodModelVersion = GlobalData.foodModelVersion
|
||||
val params = HashMap<String, RequestBody>()
|
||||
params["foodId"] = foodId.toRequestBody()
|
||||
params["foodName"] = foodName.toRequestBody()
|
||||
params["version"] = foodModelVersion.toRequestBody()
|
||||
val files = listOf(imageFile)
|
||||
val vectors = listOf(imageVector)
|
||||
val foodVectorList = vectors.map {
|
||||
it.joinToString(
|
||||
separator = ",",
|
||||
prefix = "[",
|
||||
postfix = "]"
|
||||
)
|
||||
}
|
||||
val foodVectorJson =
|
||||
foodVectorList.joinToString(separator = ",", prefix = "[", postfix = "]")
|
||||
Timber.tag(TAG).d("json=$foodVectorJson")
|
||||
params["foodVector"] = foodVectorJson.toRequestBody()
|
||||
val idList = viewModel.uploadCollectFoodPics(files, params)
|
||||
if (idList.isNullOrEmpty()) {
|
||||
loadRemindDialog("未返回id")
|
||||
Timber.tag(TAG).d("idList为空")
|
||||
return
|
||||
}
|
||||
Timber.tag(TAG)
|
||||
.d("uploadCollectFoodPics-已采集向量总数:${box.all.filter { it.isDel.not() }.size}条")
|
||||
val filterList = box.all.filter { it.collectId == idList[0] }
|
||||
if (filterList.isNotEmpty()) {
|
||||
loadRemindDialog("返回的id:${idList[0]}已存在")
|
||||
return
|
||||
}
|
||||
box.put(
|
||||
Food(
|
||||
collectId = idList[0],
|
||||
foodId = foodId,
|
||||
foodName = foodName,
|
||||
foodVector = imageVector,
|
||||
version = foodModelVersion
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun loadRemindDialog(msg: String) {
|
||||
runOnUiThread {
|
||||
RemindDialog(
|
||||
context = context,
|
||||
content = msg,
|
||||
confirmBlock = {}
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var box: Box<Food>
|
||||
|
||||
private fun uri2File(uri: Uri, block: (File?, FloatArray?) -> Unit) {
|
||||
ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
|
||||
val imageVector = try {
|
||||
FoodModule.bitmap2FloatArray(bitmap)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return@let
|
||||
}
|
||||
val imageFile = BitmapSaver.saveToAppFilesDir(
|
||||
bitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${imageFile?.absolutePath}")
|
||||
block(imageFile, imageVector)
|
||||
if (bitmap.isRecycled.not()) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
//SensorScaleUtils.closeScale()
|
||||
faceTaskJob?.cancel()
|
||||
@@ -1091,13 +1221,18 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
hideWaitingDialog()
|
||||
Timber.d("registerDataChange photoUri 识别数据名称:$foodName")
|
||||
binding.flPay.run {
|
||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
//0-计费,1-不计费
|
||||
if (chargeMode == 0) visible() else gone()
|
||||
}
|
||||
if (TextUtils.isEmpty(foodName)) {
|
||||
LightManager.closeGreenLight()
|
||||
LightManager.closeRedLight()
|
||||
//binding.layoutRescan.visibility = View.VISIBLE
|
||||
binding.flPay.visible()
|
||||
|
||||
binding.tvToSearch.let {
|
||||
it.text = "未识别到,去手动搜索"
|
||||
it.text = "未识别到,手动搜索"
|
||||
it.visible()
|
||||
}
|
||||
} else {
|
||||
@@ -1117,4 +1252,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
// @Subscribe(threadMode = ThreadMode.MAIN)
|
||||
// public fun onResetBox(event: ResetBoxEvent) {
|
||||
// ObjectBox.boxStore.close()
|
||||
// ObjectBox.init(this)
|
||||
// }
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user