Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
A
Android_Catering_service
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姜天宇
Android_Catering_service
Commits
a6cc253b
Commit
a6cc253b
authored
Apr 24, 2025
by
姜天宇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:移除了目标检测阈值限制;增加本地图片学习;增加LOGO;修复安装APK后出现两个图标的问题;
parent
5bc4a8c6
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
262 additions
and
82 deletions
+262
-82
build.gradle
app/build.gradle
+28
-4
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+1
-1
ic_wm_catering.png
app/src/main/res/mipmap-xxxhdpi/ic_wm_catering.png
+0
-0
build.gradle
camera/build.gradle
+4
-0
build.gradle
common/build.gradle
+4
-0
build.gradle
core/build.gradle
+4
-0
catering_dish_detection.cpp
core/src/main/cpp/catering_dish_detection.cpp
+8
-17
catering_plate_detection.cpp
core/src/main/cpp/catering_plate_detection.cpp
+8
-17
TargetDetectionRepository.java
.../com/wmdigit/core/catering/TargetDetectionRepository.java
+45
-0
build.gradle
data-local/build.gradle
+1
-1
DiskRepository.java
...java/com/wmdigit/data/disk/repository/DiskRepository.java
+56
-27
build.gradle
data-remote/build.gradle
+3
-3
gradle.properties
gradle.properties
+6
-1
history.txt
history.txt
+4
-0
AndroidManifest.xml
module-demo/src/main/AndroidManifest.xml
+0
-2
AndroidManifest.xml
module-setting/src/main/AndroidManifest.xml
+4
-6
DataManagerFragment.java
...ava/com/wmdigit/setting/fragment/DataManagerFragment.java
+18
-1
DataManagerViewModel.java
...a/com/wmdigit/setting/viewmodel/DataManagerViewModel.java
+62
-0
ic_learn_local_images.png
...e-setting/src/main/res/drawable/ic_learn_local_images.png
+0
-0
strings.xml
module-setting/src/main/res/values/strings.xml
+6
-0
AndroidManifest.xml
service/src/main/AndroidManifest.xml
+0
-2
No files found.
app/build.gradle
View file @
a6cc253b
...
...
@@ -3,16 +3,35 @@ plugins {
id
'org.jetbrains.kotlin.android'
}
def
APP_VERSION_CODE
=
1000201
def
APP_VERSION_NAME
=
"1.0.2.1"
android
{
namespace
'com.wmdigit.cateringdetect'
compileSdk
33
signingConfigs
{
debug
{
storeFile
file
(
Keystore
)
storePassword
'wmdigit'
keyAlias
'wm'
keyPassword
'wmdigit'
}
release
{
storeFile
file
(
Keystore
)
storePassword
'wmdigit'
keyAlias
'wm'
keyPassword
'wmdigit'
}
}
defaultConfig
{
applicationId
"com.wmdigit.cateringdetect"
minSdk
2
6
minSdk
2
4
targetSdk
33
versionCode
1000201
versionName
"v1.0.2.1"
versionCode
APP_VERSION_CODE
versionName
APP_VERSION_NAME
signingConfig
signingConfigs
.
release
ndk
{
abiFilters
'armeabi-v7a'
...
...
@@ -29,7 +48,7 @@ android {
buildTypes
{
debug
{
buildConfigField
'String'
,
'POS_URL'
,
'"https://se
-test.frp
.wmdigit.com/"'
buildConfigField
'String'
,
'POS_URL'
,
'"https://se.wmdigit.com/"'
resValue
"string"
,
"app_name"
,
"餐饮服务-debug"
minifyEnabled
false
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
...
...
@@ -48,6 +67,11 @@ android {
kotlinOptions
{
jvmTarget
=
'17'
}
android
.
applicationVariants
.
all
{
variant
->
variant
.
outputs
.
all
{
outputFileName
=
'WmCateringService-v'
+
APP_VERSION_NAME
+
'-'
+
variant
.
buildType
.
name
+
'.apk'
}
}
buildFeatures
{
viewBinding
true
dataBinding
true
...
...
app/src/main/AndroidManifest.xml
View file @
a6cc253b
...
...
@@ -30,7 +30,7 @@
android:largeHeap=
"true"
android:dataExtractionRules=
"@xml/data_extraction_rules"
android:fullBackupContent=
"@xml/backup_rules"
android:icon=
"@mipmap/ic_
launcher
"
android:icon=
"@mipmap/ic_
wm_catering
"
android:label=
"@string/app_name"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
...
...
app/src/main/res/mipmap-xxxhdpi/ic_wm_catering.png
0 → 100644
View file @
a6cc253b
222 KB
camera/build.gradle
View file @
a6cc253b
...
...
@@ -18,6 +18,10 @@ android {
minifyEnabled
false
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
debug
{
minifyEnabled
true
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
}
compileOptions
{
sourceCompatibility
JavaVersion
.
VERSION_1_8
...
...
common/build.gradle
View file @
a6cc253b
...
...
@@ -25,6 +25,10 @@ android {
minifyEnabled
false
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
debug
{
minifyEnabled
true
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
}
compileOptions
{
sourceCompatibility
JavaVersion
.
VERSION_17
...
...
core/build.gradle
View file @
a6cc253b
...
...
@@ -34,6 +34,10 @@ android {
minifyEnabled
false
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
debug
{
minifyEnabled
true
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
}
compileOptions
{
...
...
core/src/main/cpp/catering_dish_detection.cpp
View file @
a6cc253b
...
...
@@ -36,14 +36,8 @@ Java_com_wmdigit_core_catering_dish_DishDetection_process(JNIEnv *env, jobject t
}
// std::string labels;
// 有效框的数量
int
rows
=
0
;
int
rows
=
output
.
output_list
.
size
()
;
int
cols
=
4
;
// 统计符合阈值的框数量
for
(
size_t
i
=
0
;
i
<
output
.
output_list
.
size
();
++
i
)
{
if
(
output
.
output_list
[
i
].
prob
>=
0.8
){
rows
++
;
}
}
if
(
rows
==
0
){
mat
.
release
();
mat_bgr
.
release
();
...
...
@@ -60,8 +54,6 @@ Java_com_wmdigit_core_catering_dish_DishDetection_process(JNIEnv *env, jobject t
LOGD
(
"size: %d"
,
output
.
output_list
.
size
());
int
size
=
output
.
output_list
.
size
();
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
// 根据阈值,筛选出有效的框
if
(
output
.
output_list
[
i
].
prob
>=
0.8
){
// 记录框的左上、右下点坐标
rect_array
[
i
][
0
]
=
(
int
)
output
.
output_list
[
i
].
x1
;
rect_array
[
i
][
1
]
=
(
int
)
output
.
output_list
[
i
].
y1
;
...
...
@@ -69,7 +61,6 @@ Java_com_wmdigit_core_catering_dish_DishDetection_process(JNIEnv *env, jobject t
rect_array
[
i
][
3
]
=
(
int
)
output
.
output_list
[
i
].
y2
;
// 记录框的特征值
feature_array
[
i
]
=
output
.
output_list
[
i
].
feat
;
}
LOGD
(
"%f, %f, %f, %f, %f"
,
output
.
output_list
[
i
].
x1
,
output
.
output_list
[
i
].
y1
,
...
...
core/src/main/cpp/catering_plate_detection.cpp
View file @
a6cc253b
...
...
@@ -31,14 +31,8 @@ Java_com_wmdigit_core_catering_plate_PlateDetection_process(JNIEnv *env, jobject
}
// std::string labels;
// 有效框的数量
int
rows
=
0
;
int
rows
=
output
.
output_list
.
size
()
;
int
cols
=
4
;
// 统计符合阈值的框数量
for
(
size_t
i
=
0
;
i
<
output
.
output_list
.
size
();
++
i
)
{
if
(
output
.
output_list
[
i
].
prob
>=
0.7
){
rows
++
;
}
}
if
(
rows
==
0
){
mat
.
release
();
mat_bgr
.
release
();
...
...
@@ -53,8 +47,6 @@ Java_com_wmdigit_core_catering_plate_PlateDetection_process(JNIEnv *env, jobject
auto
**
feature_array
=
(
float
**
)
malloc
(
rows
*
sizeof
(
float
*
));
// 遍历识别结果
for
(
size_t
i
=
0
;
i
<
output
.
output_list
.
size
();
++
i
)
{
// 根据阈值,筛选出有效的框
if
(
output
.
output_list
[
i
].
prob
>=
0.75
){
// 记录框的左上、右下点坐标
rect_array
[
i
][
0
]
=
(
int
)
output
.
output_list
[
i
].
x1
;
rect_array
[
i
][
1
]
=
(
int
)
output
.
output_list
[
i
].
y1
;
...
...
@@ -62,7 +54,6 @@ Java_com_wmdigit_core_catering_plate_PlateDetection_process(JNIEnv *env, jobject
rect_array
[
i
][
3
]
=
(
int
)
output
.
output_list
[
i
].
y2
;
// 记录框的特征值
feature_array
[
i
]
=
output
.
output_list
[
i
].
feat
;
}
LOGD
(
"%f, %f, %f, %f, %f"
,
output
.
output_list
[
i
].
x1
,
output
.
output_list
[
i
].
y1
,
...
...
core/src/main/java/com/wmdigit/core/catering/TargetDetectionRepository.java
View file @
a6cc253b
package
com
.
wmdigit
.
core
.
catering
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
com.wmdigit.common.model.CropValueDTO
;
import
com.wmdigit.core.catering.dish.DishDetection
;
...
...
@@ -9,6 +12,13 @@ import com.wmdigit.core.catering.plate.PlateDetection;
import
com.wmdigit.data.mmkv.repository.AiLocalRepository
;
import
com.wmdigit.data.mmkv.repository.CropLocalRepository
;
import
java.util.List
;
import
io.reactivex.Observable
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.schedulers.Schedulers
;
/**
* 目标检测管理类
* @author dizi
...
...
@@ -89,6 +99,41 @@ public class TargetDetectionRepository {
return
result
;
}
/**
* 推理目标检测处理后的图片
* 该方法用于处理在目标检测后对图片进行进一步推理,以获取图片的特征向量
* 主要步骤包括:获取裁剪参数、创建背景画布、将原图居中绘制在背景上、进行目标检测推理、返回特征向量
*
* @param bitmap 待处理的图片位图
* @return 返回图片的特征向量,如果没有检测到目标或发生错误,则返回null
*/
public
float
[]
processImageAfterTargetDetection
(
Bitmap
bitmap
){
// 获取裁剪参数,用于确定最终图片的尺寸
CropValueDTO
cropValueDTO
=
CropLocalRepository
.
getInstance
().
getCropValue
();
// 确定最终图片的宽度和高度,取原图和裁剪参数中的最大值
int
width
=
Math
.
max
(
bitmap
.
getWidth
(),
cropValueDTO
.
getWidth
());
int
height
=
Math
.
max
(
bitmap
.
getHeight
(),
cropValueDTO
.
getHeight
());
// 创建一个空图背景
Bitmap
background
=
Bitmap
.
createBitmap
(
width
,
height
,
Bitmap
.
Config
.
ARGB_8888
);
Canvas
backgroundCanvas
=
new
Canvas
(
background
);
// 填充背景颜色为灰色
backgroundCanvas
.
drawColor
(
Color
.
rgb
(
127
,
127
,
127
));
// 计算原图在背景上的居中位置
int
left
=
(
width
-
bitmap
.
getWidth
())
/
2
;
int
top
=
(
height
-
bitmap
.
getHeight
())
/
2
;
// 在背景上创建最终的画布,并将原图居中绘制上去
Canvas
finalCanvas
=
new
Canvas
(
background
);
finalCanvas
.
drawBitmap
(
bitmap
,
left
,
top
,
new
Paint
());
// 使用目标检测模型对处理后的图片进行推理
TargetDetectResult
result
=
targetDetection
.
processImage
(
background
);
// 如果检测到目标并且存在特征向量,则返回第一个特征向量
if
(
result
!=
null
&&
result
.
getFeatures
()
!=
null
&&
result
.
getFeatures
().
length
>
0
){
return
result
.
getFeatures
()[
0
];
}
// 如果没有检测到目标或没有特征向量,则返回null
return
null
;
}
/**
* 释放资源
*/
...
...
data-local/build.gradle
View file @
a6cc253b
...
...
@@ -7,7 +7,7 @@ android {
compileSdk
33
defaultConfig
{
minSdk
2
6
minSdk
2
4
testInstrumentationRunner
"androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles
"consumer-rules.pro"
...
...
data-local/src/main/java/com/wmdigit/data/disk/repository/DiskRepository.java
View file @
a6cc253b
...
...
@@ -107,33 +107,6 @@ public class DiskRepository {
}
}
/* public void cleanOrphanedImages(){
String folderPath = LocalDataModule.getAppContext().getExternalFilesDir(FOLDER_NAME_PRODUCT_LEARNING_RECORDS).getAbsolutePath();
File rootImageDir = new File(folderPath);
if (!rootImageDir.exists()){
return;
}
long startTime = System.currentTimeMillis();
Set<String> dbImgPaths = new ConcurrentSkipListSet<>(FeaturesRepository.getInstance().getAllImgPath());
try (Stream<Path> pathStream = Files.walk(rootImageDir.toPath())){
pathStream
.parallel()
.filter(Files::isRegularFile)
.forEach(filePath -> {
String absPath = filePath.toString();
if (!dbImgPaths.contains(absPath)) {
try {
Files.delete(filePath);
} catch (IOException e) {
XLog.e(e);
}
}
});
}
catch (Exception e){
XLog.e(e);
}
}*/
/**
* 将产品的学习记录打包成zip文件
...
...
@@ -187,4 +160,60 @@ public class DiskRepository {
}
}
/**
* 查询本地学习图片
*
* 本方法用于扫描应用外部文件目录下特定文件夹中的所有jpg图片,并返回这些图片的绝对路径列表
* 主要步骤包括:
* 1. 获取应用外部文件目录下的特定文件夹(产品学习记录文件夹)
* 2. 检查该文件夹是否存在,以及是否包含子文件夹
* 3. 遍历每个子文件夹,寻找jpg格式的图片
* 4. 将找到的图片的绝对路径添加到列表中并返回
*
* @return 包含所有找到的学习图片绝对路径的列表
*/
public
List
<
String
>
searchLocalLearnedImages
(){
// 初始化图片路径列表
List
<
String
>
paths
=
new
ArrayList
<>();
// 获取产品学习记录文件夹的绝对路径
String
productLearningRecordsRootPath
=
LocalDataModule
.
getAppContext
().
getExternalFilesDir
(
FOLDER_NAME_PRODUCT_LEARNING_RECORDS
).
getAbsolutePath
();
// 创建根文件夹对象
File
rootFolder
=
new
File
(
productLearningRecordsRootPath
);
// 获取根文件夹下的所有子文件夹
File
[]
subFolders
=
rootFolder
.
listFiles
();
// 如果根文件夹不存在或没有子文件夹,则直接返回空的路径列表
if
(!
rootFolder
.
exists
()
||
subFolders
==
null
||
subFolders
.
length
==
0
){
return
paths
;
}
// 遍历所有子文件夹
for
(
File
subFolder
:
subFolders
){
// 如果当前子文件夹不是目录,则跳过
if
(!
subFolder
.
isDirectory
()){
continue
;
}
// 获取当前子文件夹下的所有文件
File
[]
images
=
subFolder
.
listFiles
();
// 遍历所有文件,寻找jpg格式的图片
for
(
File
image
:
images
){
// 如果文件不是jpg格式,则跳过
if
(!
image
.
getName
().
endsWith
(
".jpg"
)){
continue
;
}
// 将找到的jpg图片的绝对路径添加到路径列表中
paths
.
add
(
image
.
getAbsolutePath
());
}
}
// 返回包含所有找到的学习图片绝对路径的列表
return
paths
;
}
}
data-remote/build.gradle
View file @
a6cc253b
...
...
@@ -15,14 +15,14 @@ android {
buildTypes
{
debug
{
buildConfigField
'String'
,
'POS_URL'
,
'"https://se
-test.frp
.wmdigit.com/"'
buildConfigField
'String'
,
'VERSION_CODE'
,
'"100020
0
"'
buildConfigField
'String'
,
'POS_URL'
,
'"https://se.wmdigit.com/"'
buildConfigField
'String'
,
'VERSION_CODE'
,
'"100020
1
"'
minifyEnabled
true
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
release
{
buildConfigField
'String'
,
'POS_URL'
,
'"https://se.wmdigit.com/"'
buildConfigField
'String'
,
'VERSION_CODE'
,
'"100020
0
"'
buildConfigField
'String'
,
'VERSION_CODE'
,
'"100020
1
"'
minifyEnabled
true
proguardFiles
getDefaultProguardFile
(
'proguard-android-optimize.txt'
),
'proguard-rules.pro'
}
...
...
gradle.properties
View file @
a6cc253b
...
...
@@ -23,3 +23,8 @@ kotlin.code.style=official
android.nonTransitiveRClass
=
true
android.enableJetifier
=
true
android.defaults.buildfeatures.buildconfig
=
true
Keystore
=
../keystore.jks
StorePassword
=
wmdigit
KeyAlias
=
wm
KeyPassword
=
wmdigit
\ No newline at end of file
history.txt
View file @
a6cc253b
...
...
@@ -17,6 +17,10 @@ v1.0.2 2024/08/06 1.增加系统信息页
14.摄像头改为UvcCamera
v1.0.2.1 2025/04/22 1.特征表增加字段记录图片地址,数据库版本升级1=>2
2.增加本地导入导出功能
3.移除了目标检测阈值限制
4.增加本地图片学习
5.增加LOGO
6.修复安装APK后出现两个图标的问题
todo 增加学习记录管理模块
todo 替换LOGO
...
...
module-demo/src/main/AndroidManifest.xml
View file @
a6cc253b
...
...
@@ -3,9 +3,7 @@
<application
android:allowBackup=
"true"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
android:theme=
"@style/Theme.CateringDetect"
>
<activity
...
...
module-setting/src/main/AndroidManifest.xml
View file @
a6cc253b
...
...
@@ -3,19 +3,17 @@
<application
android:allowBackup=
"true"
android:icon=
"@mipmap/ic_launcher"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
android:theme=
"@style/Theme.CateringDetect"
>
<activity
android:name=
".SettingActivity"
android:exported=
"true"
android:windowSoftInputMode=
"stateVisible|adjustPan"
>
<intent-filter
>
<action
android:name=
"android.intent.action.MAIN"
/
>
<!-- <intent-filter>--
>
<!-- <action android:name="android.intent.action.MAIN" />--
>
<category
android:name=
"android.intent.category.LAUNCHER"
/
>
</intent-filter
>
<!-- <category android:name="android.intent.category.LAUNCHER" />--
>
<!-- </intent-filter>--
>
</activity>
</application>
...
...
module-setting/src/main/java/com/wmdigit/setting/fragment/DataManagerFragment.java
View file @
a6cc253b
...
...
@@ -62,11 +62,16 @@ public class DataManagerFragment extends BaseMvvmFragment<DataManagerViewModel,
break
;
case
4
:
// 学习本地图片
learnLocalImages
();
break
;
case
5
:
// 解绑POS
unbindPos
();
break
;
case
5
:
case
6
:
// 下载远程工具
downloadRemoteTool
();
break
;
...
...
@@ -77,6 +82,18 @@ public class DataManagerFragment extends BaseMvvmFragment<DataManagerViewModel,
});
}
/**
* 学习本地图片
*/
private
void
learnLocalImages
(){
mSecondConfirmWindow
.
setTitle
(
getString
(
com
.
wmdigit
.
common
.
R
.
string
.
prompt
))
.
setContent
(
getString
(
R
.
string
.
confirm_learn_local_images
))
.
setClickListener
(()
->
{
mViewModel
.
learnLocalImages
();
})
.
showWindow
();
}
/**
* 导入学习数据
*/
...
...
module-setting/src/main/java/com/wmdigit/setting/viewmodel/DataManagerViewModel.java
View file @
a6cc253b
package
com
.
wmdigit
.
setting
.
viewmodel
;
import
android.app.Application
;
import
android.graphics.Bitmap
;
import
android.graphics.BitmapFactory
;
import
androidx.annotation.NonNull
;
import
com.elvishew.xlog.XLog
;
import
com.wmdigit.common.base.mvvm.BaseViewModel
;
import
com.wmdigit.common.base.mvvm.SingleLiveEvent
;
import
com.wmdigit.core.catering.TargetDetectionRepository
;
import
com.wmdigit.core.hnsw.HnswRepository
;
import
com.wmdigit.data.database.repository.ExportFeaturesRepository
;
import
com.wmdigit.data.database.repository.FeaturesRepository
;
import
com.wmdigit.data.database.repository.ProductsRepository
;
import
com.wmdigit.data.disk.repository.DiskRepository
;
import
com.wmdigit.data.mmkv.repository.CropLocalRepository
;
import
com.wmdigit.network.repository.UserRemoteRepository
;
import
com.wmdigit.setting.R
;
import
com.wmdigit.setting.model.FuncButton
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
import
io.reactivex.Observable
;
import
io.reactivex.ObservableSource
;
import
io.reactivex.Observer
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.functions.Function
;
import
io.reactivex.schedulers.Schedulers
;
/**
* 数据管理页ViewModel
...
...
@@ -40,10 +52,60 @@ public class DataManagerViewModel extends BaseViewModel {
funcButtons
.
add
(
new
FuncButton
(
getApplication
().
getString
(
R
.
string
.
import_learning_data
),
R
.
drawable
.
ic_download_learning_data
));
funcButtons
.
add
(
new
FuncButton
(
getApplication
().
getString
(
R
.
string
.
module_setting_clear_learning_data
),
R
.
drawable
.
ic_clear_data_red
));
funcButtons
.
add
(
new
FuncButton
(
getApplication
().
getString
(
R
.
string
.
module_setting_clear_products
),
R
.
drawable
.
ic_clean_learning_data
));
funcButtons
.
add
(
new
FuncButton
(
getApplication
().
getString
(
R
.
string
.
module_setting_learn_local_images
),
R
.
drawable
.
ic_learn_local_images
));
funcButtons
.
add
(
new
FuncButton
(
getApplication
().
getString
(
R
.
string
.
module_setting_unbind
),
R
.
drawable
.
ic_unbind
));
funcButtons
.
add
(
new
FuncButton
(
getApplication
().
getString
(
R
.
string
.
module_setting_download_remote_tool
),
R
.
drawable
.
ic_download_remote
));
}
/**
* 学习本地图像功能
* 该方法用于处理本地图像学习过程,包括检查是否已裁剪图像、是否有图像可供学习,
* 以及实际的学习过程和结果处理
*/
public
void
learnLocalImages
(){
// 检查是否已裁剪图像,如果没有则提示用户先进行裁剪
if
(!
CropLocalRepository
.
getInstance
().
getHasCropped
()){
toastMessage
.
postValue
(
getApplication
().
getString
(
R
.
string
.
module_setting_please_crop_first
));
return
;
}
// 判断是否有数据
List
<
String
>
imagePaths
=
DiskRepository
.
getInstance
().
searchLocalLearnedImages
();
// 如果没有图像可供学习,则提示用户
if
(
imagePaths
.
size
()
==
0
){
toastMessage
.
postValue
(
getApplication
().
getString
(
R
.
string
.
no_learning_local_image
));
return
;
}
// 开始学习图像,显示加载中信息
loadingProgressText
.
postValue
(
getApplication
().
getString
(
R
.
string
.
learning_local_images
));
compositeDisposable
.
add
(
Observable
.
create
(
emitter
->
{
// 遍历所有图像,进行学习处理
for
(
String
path
:
imagePaths
){
XLog
.
d
(
"正在学习"
+
path
);
Bitmap
bitmap
=
BitmapFactory
.
decodeFile
(
path
);
float
[]
features
=
TargetDetectionRepository
.
getInstance
().
processImageAfterTargetDetection
(
bitmap
);
if
(
features
!=
null
){
String
productCode
=
new
File
(
path
).
getParentFile
().
getName
();
FeaturesRepository
.
getInstance
().
insert
(
productCode
,
features
,
path
);
}
}
emitter
.
onNext
(
true
);
}).
flatMap
(
obj
->
HnswRepository
.
getInstance
().
initializeHnswData
())
.
subscribeOn
(
Schedulers
.
io
())
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
success
->{
// 学习成功,隐藏加载中信息并提示用户成功
loadingProgressText
.
postValue
(
""
);
toastMessage
.
postValue
(
getApplication
().
getString
(
R
.
string
.
learn_local_image_success
));
},
error
->{
// 学习失败,隐藏加载中信息并提示用户失败
loadingProgressText
.
postValue
(
""
);
toastMessage
.
postValue
(
getApplication
().
getString
(
R
.
string
.
learn_local_image_fail
));
})
);
}
/**
* 导出学习数据
...
...
module-setting/src/main/res/drawable/ic_learn_local_images.png
0 → 100644
View file @
a6cc253b
3.59 KB
module-setting/src/main/res/values/strings.xml
View file @
a6cc253b
...
...
@@ -33,6 +33,7 @@
<string
name=
"module_setting_confirm_clear_learning_data"
>
请确认是否清空学习数据?
</string>
<string
name=
"module_setting_confirm_clear_product_data"
>
请确认是否清空商品数据?
</string>
<string
name=
"module_setting_clear_products"
>
清空商品数据
</string>
<string
name=
"module_setting_learn_local_images"
>
学习本地图片
</string>
<string
name=
"module_setting_unbind"
>
SN解绑
</string>
<string
name=
"module_setting_download_remote_tool"
>
下载远程工具
</string>
<string
name=
"module_setting_ai_config"
>
AI配置
</string>
...
...
@@ -52,12 +53,17 @@
<string
name=
"import_learning_data"
>
导入学习数据
</string>
<string
name=
"confirm_export_learning_data"
>
请确认是否导出学习数据?
</string>
<string
name=
"confirm_import_learning_data"
>
请确认是否导入学习数据?
</string>
<string
name=
"confirm_learn_local_images"
>
请确认是否将本地图片加入学习库?
</string>
<string
name=
"learning_local_images"
>
正在学习本地图片,请勿中断操作
</string>
<string
name=
"exporting_learning_data"
>
正在导出学习数据,请勿中断操作
</string>
<string
name=
"importing_learning_data"
>
正在导入学习数据,请勿中断操作
</string>
<string
name=
"export_learning_data_no_data"
>
本地没有学习数据,导出终止
</string>
<string
name=
"no_learning_local_image"
>
本地没有可学习的图片,学习终止
</string>
<string
name=
"export_success"
>
学习数据导出成功
</string>
<string
name=
"export_failed"
>
学习数据导出失败,请联系运维人员
</string>
<string
name=
"import_database_file_not_exits"
>
待导入的数据库文件不存在
</string>
<string
name=
"import_success"
>
导入成功
</string>
<string
name=
"import_failed"
>
导入失败
</string>
<string
name=
"learn_local_image_success"
>
学习本地图片成功
</string>
<string
name=
"learn_local_image_fail"
>
学习本地图片失败
</string>
</resources>
\ No newline at end of file
service/src/main/AndroidManifest.xml
View file @
a6cc253b
...
...
@@ -2,8 +2,6 @@
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<application
android:allowBackup=
"true"
android:icon=
"@mipmap/ic_launcher"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
android:theme=
"@style/Theme.CateringDetect"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment