Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
Oil_Level_Recognition_System
Overview
Overview
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
Administrator
Oil_Level_Recognition_System
Commits
29a54b5f
Commit
29a54b5f
authored
Dec 01, 2025
by
Yuhaibo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
81c47ac5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
218 additions
and
24 deletions
+218
-24
1.spec
1.spec
+1
-1
app.py
app.py
+1
-1
app.py
handlers/app.py
+63
-0
model_test_handler.py
handlers/modelpage/model_test_handler.py
+28
-10
model_training_handler.py
handlers/modelpage/model_training_handler.py
+0
-0
model_trainingworker_handler.py
handlers/modelpage/model_trainingworker_handler.py
+0
-0
view_handler.py
handlers/view_handler.py
+3
-2
args.yaml
runs/segment/train/args.yaml
+106
-0
modelset_page.py
widgets/modelpage/modelset_page.py
+7
-1
general_set.py
widgets/videopage/general_set.py
+9
-9
No files found.
1.spec
View file @
29a54b5f
...
@@ -306,7 +306,7 @@ exe = EXE(
...
@@ -306,7 +306,7 @@ exe = EXE(
bootloader_ignore_signals
=
False
,
bootloader_ignore_signals
=
False
,
strip
=
False
,
# 不strip二进制文件
strip
=
False
,
# 不strip二进制文件
upx
=
False
,
# 不使用UPX压缩(避免兼容性问题)
upx
=
False
,
# 不使用UPX压缩(避免兼容性问题)
console
=
Tru
e
,
# True表示显示控制台窗口(用于调试)
console
=
Fals
e
,
# True表示显示控制台窗口(用于调试)
disable_windowed_traceback
=
False
,
disable_windowed_traceback
=
False
,
target_arch
=
None
,
target_arch
=
None
,
codesign_identity
=
None
,
codesign_identity
=
None
,
...
...
app.py
View file @
29a54b5f
...
@@ -147,7 +147,7 @@ except ImportError:
...
@@ -147,7 +147,7 @@ except ImportError:
# 支持相对导入(作为模块运行)和绝对导入(独立运行)
# 支持相对导入(作为模块运行)和绝对导入(独立运行)
try
:
try
:
from
.widgets
import
MenuBar
from
.widgets
import
MenuBar
from
.widgets.font_manager
import
FontManager
# 导入所有处理器 (Mixin类)
# 导入所有处理器 (Mixin类)
from
.handlers
import
(
from
.handlers
import
(
ChannelPanelHandler
,
ChannelPanelHandler
,
...
...
handlers/app.py
View file @
29a54b5f
...
@@ -689,6 +689,9 @@ class MainWindow(
...
@@ -689,6 +689,9 @@ class MainWindow(
# 默认显示模式1
# 默认显示模式1
self
.
videoLayoutStack
.
setCurrentIndex
(
0
)
self
.
videoLayoutStack
.
setCurrentIndex
(
0
)
self
.
_video_layout_mode
=
0
# 0=默认模式, 1=曲线模式
self
.
_video_layout_mode
=
0
# 0=默认模式, 1=曲线模式
# 初次创建页面后刷新一次按钮状态(默认布局)
self
.
_updateCurveButtonsByMission
()
return
page
return
page
...
@@ -989,6 +992,12 @@ class MainWindow(
...
@@ -989,6 +992,12 @@ class MainWindow(
# ========== 曲线面板信号 ==========
# ========== 曲线面板信号 ==========
self
.
curvePanel
.
backClicked
.
connect
(
self
.
switchToRealTimeDetectionPage
)
# 返回实时检测管理页面
self
.
curvePanel
.
backClicked
.
connect
(
self
.
switchToRealTimeDetectionPage
)
# 返回实时检测管理页面
# 页面堆栈切换与视频子布局切换时,刷新曲线按钮状态
if
hasattr
(
self
,
'stackedWidget'
):
self
.
stackedWidget
.
currentChanged
.
connect
(
self
.
_onMainStackChanged
)
if
hasattr
(
self
,
'videoLayoutStack'
):
self
.
videoLayoutStack
.
currentChanged
.
connect
(
self
.
_onVideoLayoutChanged
)
def
_initMenuBar
(
self
):
def
_initMenuBar
(
self
):
"""初始化菜单栏(委托给MenuBarHandler处理)"""
"""初始化菜单栏(委托给MenuBarHandler处理)"""
...
@@ -1026,6 +1035,60 @@ class MainWindow(
...
@@ -1026,6 +1035,60 @@ class MainWindow(
"""显示实时检测管理页面"""
"""显示实时检测管理页面"""
self
.
stackedWidget
.
setCurrentWidget
(
self
.
videoPage
)
self
.
stackedWidget
.
setCurrentWidget
(
self
.
videoPage
)
self
.
statusBar
()
.
showMessage
(
self
.
tr
(
"当前页面: 实时检测管理"
))
self
.
statusBar
()
.
showMessage
(
self
.
tr
(
"当前页面: 实时检测管理"
))
# 切到视频页时刷新默认布局下的曲线按钮状态
self
.
_updateCurveButtonsByMission
()
def
_onMainStackChanged
(
self
,
index
:
int
):
"""主页面堆栈变化时,根据当前页面刷新按钮状态"""
try
:
if
index
==
self
.
PAGE_VIDEO
:
self
.
_updateCurveButtonsByMission
()
except
Exception
:
pass
def
_onVideoLayoutChanged
(
self
,
index
:
int
):
"""视频页面子布局变化时刷新按钮状态"""
try
:
self
.
_video_layout_mode
=
index
# 仅在默认模式下需要检查并启用曲线按钮
if
index
==
0
:
self
.
_updateCurveButtonsByMission
()
except
Exception
:
pass
def
_updateCurveButtonsByMission
(
self
):
"""
根据每个通道的任务标签是否有任务,启用或禁用“查看曲线”按钮。
仅在默认模式布局(任务表格 + 2x2通道面板)下生效。
"""
try
:
# 仅在视频页默认布局下处理
if
(
not
hasattr
(
self
,
'stackedWidget'
)
or
self
.
stackedWidget
.
currentIndex
()
!=
self
.
PAGE_VIDEO
or
not
hasattr
(
self
,
'videoLayoutStack'
)
or
self
.
videoLayoutStack
.
currentIndex
()
!=
0
):
return
# 遍历四个通道面板
for
panel
in
getattr
(
self
,
'channelPanels'
,
[]):
# 任务标签文本
mission_label
=
getattr
(
panel
,
'taskLabel'
,
None
)
text
=
''
if
mission_label
and
hasattr
(
mission_label
,
'text'
):
text
=
mission_label
.
text
()
.
strip
()
# 判断是否有有效任务
has_mission
=
bool
(
text
)
and
text
not
in
(
'请选择任务'
,
'未选择任务'
)
# 找到“查看曲线”按钮并设置可用性
curve_btn
=
getattr
(
panel
,
'btn_curve'
,
None
)
if
curve_btn
and
hasattr
(
curve_btn
,
'setEnabled'
):
curve_btn
.
setEnabled
(
has_mission
)
except
Exception
:
# 安静失败,不影响主流程
pass
def
showModelPage
(
self
):
def
showModelPage
(
self
):
"""显示模型管理页面"""
"""显示模型管理页面"""
...
...
handlers/modelpage/model_test_handler.py
View file @
29a54b5f
...
@@ -1207,7 +1207,7 @@ class ModelTestHandler:
...
@@ -1207,7 +1207,7 @@ class ModelTestHandler:
height
=
area_data
[
'liquid_height'
]
height
=
area_data
[
'liquid_height'
]
print
(
f
"[液位检测] {area_name}: {height}mm"
)
print
(
f
"[液位检测] {area_name}: {height}mm"
)
self
.
_showTestDetectionResult
(
test_frame
,
detection_result
,
boxes
,
bottoms
,
tops
)
self
.
_showTestDetectionResult
(
test_frame
,
detection_result
,
boxes
,
bottoms
,
tops
,
actual_heights
)
print
(
f
"[液位检测] 检测结果已显示在右侧面板中"
)
print
(
f
"[液位检测] 检测结果已显示在右侧面板中"
)
else
:
else
:
...
@@ -1217,7 +1217,7 @@ class ModelTestHandler:
...
@@ -1217,7 +1217,7 @@ class ModelTestHandler:
print
(
f
" 2. 检测区域设置不正确(位置偏移)"
)
print
(
f
" 2. 检测区域设置不正确(位置偏移)"
)
print
(
f
" 3. 图像质量或光照条件不佳"
)
print
(
f
" 3. 图像质量或光照条件不佳"
)
self
.
_showTestDetectionResult
(
test_frame
,
None
,
boxes
,
bottoms
,
tops
)
self
.
_showTestDetectionResult
(
test_frame
,
None
,
boxes
,
bottoms
,
tops
,
actual_heights
)
print
(
f
"[液位检测] 原始图像和标注信息已显示在右侧面板中"
)
print
(
f
"[液位检测] 原始图像和标注信息已显示在右侧面板中"
)
...
@@ -1227,7 +1227,7 @@ class ModelTestHandler:
...
@@ -1227,7 +1227,7 @@ class ModelTestHandler:
traceback
.
print_exc
()
traceback
.
print_exc
()
try
:
try
:
self
.
_showTestDetectionResult
(
test_frame
,
None
,
boxes
,
bottoms
,
tops
)
self
.
_showTestDetectionResult
(
test_frame
,
None
,
boxes
,
bottoms
,
tops
,
actual_heights
)
print
(
f
"[液位检测] 原始图像已显示(检测失败)"
)
print
(
f
"[液位检测] 原始图像已显示(检测失败)"
)
except
Exception
as
show_error
:
except
Exception
as
show_error
:
print
(
f
"[液位检测] 显示原始图像也失败: {show_error}"
)
print
(
f
"[液位检测] 显示原始图像也失败: {show_error}"
)
...
@@ -1518,8 +1518,17 @@ class ModelTestHandler:
...
@@ -1518,8 +1518,17 @@ class ModelTestHandler:
if
hasattr
(
self
,
'_detection_stopped'
):
if
hasattr
(
self
,
'_detection_stopped'
):
print
(
f
"[视频检测] 最终停止标志: {self._detection_stopped}"
)
print
(
f
"[视频检测] 最终停止标志: {self._detection_stopped}"
)
def
_showTestDetectionResult
(
self
,
original_frame
,
detection_result
,
boxes
,
bottoms
,
tops
):
def
_showTestDetectionResult
(
self
,
original_frame
,
detection_result
,
boxes
,
bottoms
,
tops
,
actual_heights
=
None
):
"""在显示面板中显示检测结果(带液位线的图像)"""
"""在显示面板中显示检测结果(带液位线的图像)
Args:
original_frame: 原始图像帧
detection_result: 检测结果
boxes: 检测框列表
bottoms: 底部点列表
tops: 顶部点列表
actual_heights: 实际容器高度列表(毫米),如果为None则使用默认值20mm
"""
try
:
try
:
from
datetime
import
datetime
from
datetime
import
datetime
...
@@ -1527,6 +1536,12 @@ class ModelTestHandler:
...
@@ -1527,6 +1536,12 @@ class ModelTestHandler:
print
(
f
"[检测结果显示] 原始帧尺寸: {original_frame.shape}"
)
print
(
f
"[检测结果显示] 原始帧尺寸: {original_frame.shape}"
)
print
(
f
"[检测结果显示] 检测区域数量: {len(boxes)}"
)
print
(
f
"[检测结果显示] 检测区域数量: {len(boxes)}"
)
print
(
f
"[检测结果显示] 检测结果: {detection_result}"
)
print
(
f
"[检测结果显示] 检测结果: {detection_result}"
)
print
(
f
"[检测结果显示] 容器实际高度: {actual_heights}"
)
# 如果没有提供actual_heights,使用默认值
if
actual_heights
is
None
:
actual_heights
=
[
20.0
]
*
len
(
boxes
)
print
(
f
"[检测结果显示] 未提供容器高度,使用默认值: {actual_heights}"
)
# 复制原始帧
# 复制原始帧
result_frame
=
original_frame
.
copy
()
result_frame
=
original_frame
.
copy
()
...
@@ -1541,6 +1556,9 @@ class ModelTestHandler:
...
@@ -1541,6 +1556,9 @@ class ModelTestHandler:
bottom_y
=
bottoms
[
i
][
1
]
bottom_y
=
bottoms
[
i
][
1
]
top_y
=
tops
[
i
][
1
]
top_y
=
tops
[
i
][
1
]
# 获取该区域的实际容器高度
actual_height
=
actual_heights
[
i
]
if
i
<
len
(
actual_heights
)
else
20.0
# 提取液位高度(默认为0)
# 提取液位高度(默认为0)
liquid_height
=
0.0
liquid_height
=
0.0
...
@@ -1550,7 +1568,7 @@ class ModelTestHandler:
...
@@ -1550,7 +1568,7 @@ class ModelTestHandler:
area_name
,
area_data
=
area_items
[
i
]
area_name
,
area_data
=
area_items
[
i
]
if
'liquid_height'
in
area_data
:
if
'liquid_height'
in
area_data
:
liquid_height
=
area_data
[
'liquid_height'
]
liquid_height
=
area_data
[
'liquid_height'
]
print
(
f
"[检测结果显示] 区域{i+1}: 检测到液位 {liquid_height}mm"
)
print
(
f
"[检测结果显示] 区域{i+1}: 检测到液位 {liquid_height}mm
(容器高度: {actual_height}mm)
"
)
else
:
else
:
print
(
f
"[检测结果显示] 区域{i+1}: 未检测到液位,使用默认值 0mm"
)
print
(
f
"[检测结果显示] 区域{i+1}: 未检测到液位,使用默认值 0mm"
)
else
:
else
:
...
@@ -1558,10 +1576,10 @@ class ModelTestHandler:
...
@@ -1558,10 +1576,10 @@ class ModelTestHandler:
else
:
else
:
print
(
f
"[检测结果显示] 区域{i+1}: 无检测结果,使用默认值 0mm"
)
print
(
f
"[检测结果显示] 区域{i+1}: 无检测结果,使用默认值 0mm"
)
# 计算液位线的Y坐标
# 计算液位线的Y坐标
- 使用实际容器高度
container_height
=
bottom_y
-
top_y
container_height
_px
=
bottom_y
-
top_y
liquid_ratio
=
min
(
1.0
,
max
(
0.0
,
liquid_height
/
100.0
))
liquid_ratio
=
min
(
1.0
,
max
(
0.0
,
liquid_height
/
actual_height
))
liquid_y
=
int
(
bottom_y
-
container_height
*
liquid_ratio
)
liquid_y
=
int
(
bottom_y
-
container_height
_px
*
liquid_ratio
)
# 绘制液位线(红色)
# 绘制液位线(红色)
cv2
.
line
(
result_frame
,
(
left
,
liquid_y
),
(
right
,
liquid_y
),
(
0
,
0
,
255
),
3
)
cv2
.
line
(
result_frame
,
(
left
,
liquid_y
),
(
right
,
liquid_y
),
(
0
,
0
,
255
),
3
)
...
...
handlers/modelpage/model_training_handler.py
View file @
29a54b5f
This diff is collapsed.
Click to expand it.
handlers/modelpage/model_trainingworker_handler.py
View file @
29a54b5f
This diff is collapsed.
Click to expand it.
handlers/view_handler.py
View file @
29a54b5f
...
@@ -439,9 +439,10 @@ class ViewHandler:
...
@@ -439,9 +439,10 @@ class ViewHandler:
for
panel
in
self
.
channelPanels
:
for
panel
in
self
.
channelPanels
:
if
hasattr
(
panel
,
'btnCurve'
):
if
hasattr
(
panel
,
'btnCurve'
):
if
target_index
==
0
:
if
target_index
==
0
:
print
(
1
)
# 曲线模式的同步布局:禁用查看曲线按钮
# 曲线模式的同步布局:禁用查看曲线按钮
panel
.
btnCurve
.
setEnabled
(
False
)
#
panel.btnCurve.setEnabled(False)
panel
.
btnCurve
.
setToolTip
(
"同步布局下无法查看曲线"
)
#
panel.btnCurve.setToolTip("同步布局下无法查看曲线")
else
:
else
:
# 曲线模式的历史回放布局:检查通道是否有任务
# 曲线模式的历史回放布局:检查通道是否有任务
has_task
=
False
has_task
=
False
...
...
runs/segment/train/args.yaml
0 → 100644
View file @
29a54b5f
task
:
segment
mode
:
train
model
:
C:\Users\admin\AppData\Local\Temp\yolo_train_wobn62b4.pt
data
:
D:/restructure/liquid_level_line_detection_system/dataset1/train\data.yaml
epochs
:
100
time
:
null
patience
:
100
batch
:
3
imgsz
:
640
save
:
true
save_period
:
1
cache
:
false
device
:
'
0'
workers
:
0
project
:
null
name
:
train
exist_ok
:
false
pretrained
:
true
optimizer
:
auto
verbose
:
true
seed
:
0
deterministic
:
true
single_cls
:
false
rect
:
false
cos_lr
:
false
close_mosaic
:
10
resume
:
false
amp
:
true
fraction
:
1.0
profile
:
false
freeze
:
null
multi_scale
:
false
compile
:
false
overlap_mask
:
true
mask_ratio
:
4
dropout
:
0.0
val
:
true
split
:
val
save_json
:
false
conf
:
null
iou
:
0.7
max_det
:
300
half
:
false
dnn
:
false
plots
:
true
source
:
null
vid_stride
:
1
stream_buffer
:
false
visualize
:
false
augment
:
false
agnostic_nms
:
false
classes
:
null
retina_masks
:
false
embed
:
null
show
:
false
save_frames
:
false
save_txt
:
false
save_conf
:
false
save_crop
:
false
show_labels
:
true
show_conf
:
true
show_boxes
:
true
line_width
:
null
format
:
torchscript
keras
:
false
optimize
:
false
int8
:
false
dynamic
:
false
simplify
:
true
opset
:
null
workspace
:
null
nms
:
false
lr0
:
0.01
lrf
:
0.01
momentum
:
0.937
weight_decay
:
0.0005
warmup_epochs
:
3.0
warmup_momentum
:
0.8
warmup_bias_lr
:
0.1
box
:
7.5
cls
:
0.5
dfl
:
1.5
pose
:
12.0
kobj
:
1.0
nbs
:
64
hsv_h
:
0.015
hsv_s
:
0.7
hsv_v
:
0.4
degrees
:
0.0
translate
:
0.1
scale
:
0.5
shear
:
0.0
perspective
:
0.0
flipud
:
0.0
fliplr
:
0.5
bgr
:
0.0
mosaic
:
1.0
mixup
:
0.0
cutmix
:
0.0
copy_paste
:
0.0
copy_paste_mode
:
flip
auto_augment
:
randaugment
erasing
:
0.4
cfg
:
null
tracker
:
botsort.yaml
save_dir
:
D:\restructure\liquid_level_line_detection_system\runs\segment\train
widgets/modelpage/modelset_page.py
View file @
29a54b5f
...
@@ -1706,7 +1706,13 @@ class ModelSetPage(QtWidgets.QWidget):
...
@@ -1706,7 +1706,13 @@ class ModelSetPage(QtWidgets.QWidget):
# 查找.dat文件(优先在根目录,兼容旧的weights子目录)
# 查找.dat文件(优先在根目录,兼容旧的weights子目录)
dat_files
=
list
(
subdir
.
glob
(
"*.dat"
))
dat_files
=
list
(
subdir
.
glob
(
"*.dat"
))
# 如果根目录没有.dat文件,检查weights子目录(兼容旧结构)
# 如果根目录没有.dat文件,检查train/weights子目录(训练后的模型)
if
not
dat_files
:
train_weights_dir
=
subdir
/
"train"
/
"weights"
if
train_weights_dir
.
exists
():
dat_files
=
list
(
train_weights_dir
.
glob
(
"*.dat"
))
# 如果train/weights也没有,检查weights子目录(兼容旧结构)
if
not
dat_files
:
if
not
dat_files
:
weights_dir
=
subdir
/
"weights"
weights_dir
=
subdir
/
"weights"
if
weights_dir
.
exists
():
if
weights_dir
.
exists
():
...
...
widgets/videopage/general_set.py
View file @
29a54b5f
...
@@ -1418,8 +1418,8 @@ class AnnotationWidget(QtWidgets.QWidget):
...
@@ -1418,8 +1418,8 @@ class AnnotationWidget(QtWidgets.QWidget):
instructions
=
[
instructions
=
[
"标注操作指南"
,
"标注操作指南"
,
"1. 左键拖动放置检测区域框"
,
"1. 左键拖动放置检测区域框"
,
"2.
拖动设置容器底
部点"
,
"2.
点击设置容器顶
部点"
,
"3.
拖动设置容器顶
部点"
,
"3.
点击设置容器底
部点"
,
"4. 双击编辑名称/高度,Enter确认"
,
"4. 双击编辑名称/高度,Enter确认"
,
"5. 双击状态标签切换状态
\n
(初始空满状态逻辑优化中,敬请期待)"
,
"5. 双击状态标签切换状态
\n
(初始空满状态逻辑优化中,敬请期待)"
,
"
\n
6. 双击空白区域完成标注"
,
"
\n
6. 双击空白区域完成标注"
,
...
@@ -1480,8 +1480,8 @@ class AnnotationWidget(QtWidgets.QWidget):
...
@@ -1480,8 +1480,8 @@ class AnnotationWidget(QtWidgets.QWidget):
instructions_en
=
[
instructions_en
=
[
"Annotation Guide"
,
"Annotation Guide"
,
"1. Drag detection box"
,
"1. Drag detection box"
,
"2. Click
bottom line
"
,
"2. Click
top point
"
,
"3. Click
top line
"
,
"3. Click
bottom point
"
,
"4. Double-click label to edit"
,
"4. Double-click label to edit"
,
"5. Enter=Confirm, ESC=Cancel"
,
"5. Enter=Confirm, ESC=Cancel"
,
"6. Repeat steps"
,
"6. Repeat steps"
,
...
@@ -1589,13 +1589,13 @@ class AnnotationWidget(QtWidgets.QWidget):
...
@@ -1589,13 +1589,13 @@ class AnnotationWidget(QtWidgets.QWidget):
# 检查点击位置是否在最后一个检测框内
# 检查点击位置是否在最后一个检测框内
if
self
.
_isPointInLastBox
(
image_x
,
image_y
):
if
self
.
_isPointInLastBox
(
image_x
,
image_y
):
self
.
annotation_engine
.
bottom_points
.
append
((
image_x
,
image_y
))
self
.
annotation_engine
.
bottom_points
.
append
((
image_x
,
image_y
))
self
.
annotation_engine
.
step
=
2
self
.
annotation_engine
.
step
=
0
# 完成一组标注,回到画框模式
self
.
_updateDisplay
()
self
.
_updateDisplay
()
elif
self
.
annotation_engine
.
step
==
2
:
# 点击顶部模式
elif
self
.
annotation_engine
.
step
==
2
:
# 点击顶部模式
# 检查点击位置是否在最后一个检测框内
# 检查点击位置是否在最后一个检测框内
if
self
.
_isPointInLastBox
(
image_x
,
image_y
):
if
self
.
_isPointInLastBox
(
image_x
,
image_y
):
self
.
annotation_engine
.
top_points
.
append
((
image_x
,
image_y
))
self
.
annotation_engine
.
top_points
.
append
((
image_x
,
image_y
))
self
.
annotation_engine
.
step
=
0
self
.
annotation_engine
.
step
=
1
# 切换到标注底部点模式
self
.
_updateDisplay
()
self
.
_updateDisplay
()
def
_onMouseMove
(
self
,
event
):
def
_onMouseMove
(
self
,
event
):
...
@@ -1644,11 +1644,11 @@ class AnnotationWidget(QtWidgets.QWidget):
...
@@ -1644,11 +1644,11 @@ class AnnotationWidget(QtWidgets.QWidget):
cy
=
(
self
.
box_start
[
1
]
+
y2
)
//
2
cy
=
(
self
.
box_start
[
1
]
+
y2
)
//
2
size
=
length
size
=
length
#
🔥 调用 add_box 方法,自动生成顶部点和底部点
#
调用 add_box 方法添加检测框
self
.
annotation_engine
.
add_box
(
cx
,
cy
,
size
)
self
.
annotation_engine
.
add_box
(
cx
,
cy
,
size
)
#
🔥 保持 step = 0(画框模式),不再需要手动点击设置顶部和底部点
#
切换到标注顶部点模式(先标顶点)
# self.annotation_engine.step = 1 # 旧逻辑:进入点击底
部点模式
self
.
annotation_engine
.
step
=
2
# step=2 是标注顶
部点模式
self
.
_updateDisplay
()
self
.
_updateDisplay
()
...
...
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