修改菜品识别逻辑
This commit is contained in:
@@ -11,6 +11,7 @@ import io.objectbox.query.Query
|
|||||||
import org.pytorch.IValue
|
import org.pytorch.IValue
|
||||||
import org.pytorch.Module
|
import org.pytorch.Module
|
||||||
import org.pytorch.torchvision.TensorImageUtils
|
import org.pytorch.torchvision.TensorImageUtils
|
||||||
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@@ -18,6 +19,7 @@ import java.io.InputStream
|
|||||||
|
|
||||||
object FoodModule {
|
object FoodModule {
|
||||||
|
|
||||||
|
private const val THRESHOLD = 0.8
|
||||||
private lateinit var module_mobile: Module
|
private lateinit var module_mobile: Module
|
||||||
private lateinit var box: Box<Food>
|
private lateinit var box: Box<Food>
|
||||||
private lateinit var embeddingsList: List<List<Float>>
|
private lateinit var embeddingsList: List<List<Float>>
|
||||||
@@ -37,7 +39,7 @@ object FoodModule {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun queryFood(bitmap: Bitmap, queryCount:Int = 15): List<String> {
|
fun queryFood(bitmap: Bitmap, queryCount: Int = 15): List<String> {
|
||||||
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(
|
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(
|
||||||
bitmap,
|
bitmap,
|
||||||
NO_MEAN_RGB, // [0.485, 0.456, 0.406] TORCHVISION_NORM_MEAN_RGB
|
NO_MEAN_RGB, // [0.485, 0.456, 0.406] TORCHVISION_NORM_MEAN_RGB
|
||||||
@@ -45,22 +47,26 @@ object FoodModule {
|
|||||||
)
|
)
|
||||||
val outputTensor = module_mobile.forward(IValue.from(inputTensor)).toTensor()
|
val outputTensor = module_mobile.forward(IValue.from(inputTensor)).toTensor()
|
||||||
val floatArray = outputTensor.dataAsFloatArray
|
val floatArray = outputTensor.dataAsFloatArray
|
||||||
return queryFood(floatArray,queryCount)
|
return queryFood(floatArray, queryCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun queryFood(floatArray: FloatArray, queryCount:Int = 15): List<String> {
|
fun queryFood(floatArray: FloatArray, queryCount: Int = 15): List<String> {
|
||||||
val query: Query<Food> = box.query(Food_.foodVector.nearestNeighbors(floatArray, queryCount)).build()
|
val query: Query<Food> =
|
||||||
|
box.query(Food_.foodVector.nearestNeighbors(floatArray, queryCount)).build()
|
||||||
//查询比较分数
|
//查询比较分数
|
||||||
// val tempList = query.findWithScores().sortedBy { it.score }.map { "${it.get().name}|${it.get().foodIdx}|${it.score}" }
|
// val tempList = query.findWithScores().sortedBy { it.score }.map { "${it.get().name}|${it.get().foodIdx}|${it.score}" }
|
||||||
val map = mutableMapOf<String, Int>()
|
val map = mutableMapOf<String, Int>()
|
||||||
query.findIdsWithScores().forEach {
|
query.findIdsWithScores().forEach {
|
||||||
val food = box.get(it.id)
|
val food = box.get(it.id)
|
||||||
|
Timber.d("${food.name}|${food.foodIdx}|${it.score}")
|
||||||
|
if (1 - it.score >= THRESHOLD) {
|
||||||
//FoodQueryResult(id = it.id, name = food.name, foodIdx = food.foodIdx, score = it.score)
|
//FoodQueryResult(id = it.id, name = food.name, foodIdx = food.foodIdx, score = it.score)
|
||||||
food.name?.let { key ->
|
food.name?.let { key ->
|
||||||
val count = map[key] ?: 0
|
val count = map[key] ?: 0
|
||||||
map.put(key, count + 1)
|
map.put(key, count + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
val list = map.entries.sortedByDescending { it.value }.map { it.key }
|
val list = map.entries.sortedByDescending { it.value }.map { it.key }
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,9 @@ class SecondaryScreenPresentation(
|
|||||||
private lateinit var itemUserNutritionBinding: ItemUserNutritionBinding
|
private lateinit var itemUserNutritionBinding: ItemUserNutritionBinding
|
||||||
private lateinit var stepChangeCallback: (Int) -> Unit
|
private lateinit var stepChangeCallback: (Int) -> Unit
|
||||||
|
|
||||||
// 上一次的计算热量结果
|
|
||||||
private var lastWeight = 0.0
|
private var detectWeight = 0.0 //识别菜品时的重量
|
||||||
|
private var lastWeight = 0.0 // 上一次的计算热量结果
|
||||||
private val debouncer = Debouncer(500)
|
private val debouncer = Debouncer(500)
|
||||||
private var recognitionTime: Long = 0L // 人脸识别时的时间
|
private var recognitionTime: Long = 0L // 人脸识别时的时间
|
||||||
private var recognitionWeight: Double = 0.0 // 人脸识别时的重量
|
private var recognitionWeight: Double = 0.0 // 人脸识别时的重量
|
||||||
@@ -288,6 +289,10 @@ class SecondaryScreenPresentation(
|
|||||||
calculateNutrition(recognitionWeight - lastWeight)
|
calculateNutrition(recognitionWeight - lastWeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateDetectWeight(weight: Double) {
|
||||||
|
detectWeight = weight * 1000 // 将千克转成克
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 余量取餐
|
* 余量取餐
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ object SensorScaleUtils {
|
|||||||
private var mSensorScale: SensorScale? = null
|
private var mSensorScale: SensorScale? = null
|
||||||
private var isOpened: Boolean = false
|
private var isOpened: Boolean = false
|
||||||
private var isRead: Boolean = false
|
private var isRead: Boolean = false
|
||||||
private var isZero = false
|
var isZero = false
|
||||||
private var callback: Callback? = {}
|
private var callback: Callback? = {}
|
||||||
private var lastWeight: Double? = null
|
private var lastWeight: Double? = null
|
||||||
|
|
||||||
@@ -118,8 +118,8 @@ object SensorScaleUtils {
|
|||||||
fun zero() {
|
fun zero() {
|
||||||
Timber.d("zero isOpened = $isOpened, mSensorScale = $mSensorScale")
|
Timber.d("zero isOpened = $isOpened, mSensorScale = $mSensorScale")
|
||||||
if (!isOpened) return
|
if (!isOpened) return
|
||||||
// isZero = true
|
|
||||||
mSensorScale?.zero {
|
mSensorScale?.zero {
|
||||||
|
isZero = true
|
||||||
Timber.d("zero 零位标定操作成功")
|
Timber.d("zero 零位标定操作成功")
|
||||||
ToastUtils.showToast("零位标定操作成功")
|
ToastUtils.showToast("零位标定操作成功")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,11 @@ fragmentKtx = "1.5.6"
|
|||||||
lifecycleViewmodelKtx = "2.8.3"
|
lifecycleViewmodelKtx = "2.8.3"
|
||||||
lifecycleRuntimeKtx = "2.8.3"
|
lifecycleRuntimeKtx = "2.8.3"
|
||||||
|
|
||||||
pytorch="1.13.0"
|
pytorch = "1.13.0"
|
||||||
|
|
||||||
|
recyclerview = "1.3.2"
|
||||||
|
|
||||||
|
#baseQuickAdapter = "4.1.2"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
|
android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
|
||||||
@@ -64,8 +68,12 @@ androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref
|
|||||||
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
||||||
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
||||||
|
|
||||||
pytorch-android={ group = "org.pytorch", name = "pytorch_android", version.ref = "pytorch" }
|
pytorch-android = { group = "org.pytorch", name = "pytorch_android", version.ref = "pytorch" }
|
||||||
pytorch-android-torchvision={ group = "org.pytorch", name = "pytorch_android_torchvision", version.ref = "pytorch" }
|
pytorch-android-torchvision = { group = "org.pytorch", name = "pytorch_android_torchvision", version.ref = "pytorch" }
|
||||||
|
|
||||||
|
#base-quick-adapter-ktx = { module = "io.github.cymchad:BaseRecyclerViewAdapterHelper4", version.ref = "baseQuickAdapter" }
|
||||||
|
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
|
||||||
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
Reference in New Issue
Block a user