Commit 08cb52c5 by Yuhaibo

1

parent 0e36f2c7
......@@ -54,7 +54,7 @@ class ModelSetHandler:
type_layout = QtWidgets.QHBoxLayout()
type_layout.addWidget(QtWidgets.QLabel("模型类型:"))
type_combo = QtWidgets.QComboBox()
type_combo.addItems(["YOLOv8", "YOLOv11", "Faster R-CNN", "SSD", "RetinaNet", "自定义"])
type_layout.addWidget(type_combo)
layout.addLayout(type_layout)
......
# AutoAnnotationDetector 使用说明
## 功能概述
`AutoAnnotationDetector` 整合了标框和标点两个功能,共享相同的检测逻辑,但提供不同的输出方式。
## 核心设计
```
输入图像 → detect() → 检测结果
┌─────────┴─────────┐
↓ ↓
get_boxes() get_points()
↓ ↓
box位置数据 点位置数据
↓ ↓
draw_boxes() draw_points()
↓ ↓
绘制框的图像 绘制点的图像
```
## 快速开始
```python
from handlers.videopage.auto_dot import AutoAnnotationDetector
import cv2
# 1. 创建检测器
detector = AutoAnnotationDetector(
model_path="path/to/model.dat",
device='cuda'
)
# 2. 加载图像
image = cv2.imread("test.jpg")
# 3. 执行核心检测(只需执行一次)
detection_result = detector.detect(
image=image,
conf_threshold=0.5,
min_area=100
)
# 4a. 获取box位置数据
boxes = detector.get_boxes(
detection_result,
padding=10,
merge_all=True # True=合并所有类别, False=按类别分别生成
)
# 4b. 获取点位置数据
points = detector.get_points(detection_result)
# 5a. 绘制box
box_image = detector.draw_boxes(image, boxes)
cv2.imwrite("box_result.jpg", box_image)
# 5b. 绘制点
point_image = detector.draw_points(image, points)
cv2.imwrite("point_result.jpg", point_image)
```
## API 详解
### 1. detect() - 核心检测方法
执行YOLO推理,返回分割结果。
**参数:**
- `image`: 输入图像 (numpy.ndarray)
- `conf_threshold`: 置信度阈值 (默认0.5)
- `min_area`: 最小面积阈值,过滤小区域 (默认100像素)
**返回:**
```python
{
'success': bool,
'masks': List[np.ndarray], # 有效的mask列表
'class_names': List[str], # 对应的类别名称
'confidences': List[float], # 对应的置信度
'image_shape': tuple # 图像尺寸 (height, width)
}
```
### 2. get_boxes() - 生成box位置数据
从检测结果生成box坐标。
**参数:**
- `detection_result`: detect()的返回结果
- `padding`: box边界扩展像素数 (默认10)
- `merge_all`: 是否合并所有类别 (默认True)
**返回:**
```python
[
{
'x1': int, # 左上角x
'y1': int, # 左上角y
'x2': int, # 右下角x
'y2': int, # 右下角y
'classes': List[str], # 包含的类别
'area': int # box面积
},
...
]
```
### 3. get_points() - 生成点位置数据
从检测结果生成容器顶部和底部点坐标。
**参数:**
- `detection_result`: detect()的返回结果
**返回:**
```python
[
{
'top': int, # 顶部y坐标
'bottom': int, # 底部y坐标
'top_x': int, # 顶部x坐标
'bottom_x': int, # 底部x坐标
'height': int, # 容器高度
'method': str, # 检测方法
'confidence': float # 置信度
},
...
]
```
### 4. draw_boxes() - 绘制box
在图像上绘制box框。
**参数:**
- `image`: 输入图像
- `boxes`: get_boxes()返回的box列表
**返回:** 绘制完成的图像
### 5. draw_points() - 绘制点
在图像上绘制顶部和底部点。
**参数:**
- `image`: 输入图像
- `points`: get_points()返回的点列表
**返回:** 绘制完成的图像
## 使用场景
### 场景1: 只需要box标注
```python
detection_result = detector.detect(image)
boxes = detector.get_boxes(detection_result, merge_all=True)
annotated_image = detector.draw_boxes(image, boxes)
```
### 场景2: 只需要点标注
```python
detection_result = detector.detect(image)
points = detector.get_points(detection_result)
annotated_image = detector.draw_points(image, points)
```
### 场景3: 同时需要box和点
```python
# 只需执行一次检测
detection_result = detector.detect(image)
# 分别获取box和点
boxes = detector.get_boxes(detection_result)
points = detector.get_points(detection_result)
# 分别绘制
box_image = detector.draw_boxes(image, boxes)
point_image = detector.draw_points(image, points)
```
### 场景4: 获取位置数据但不绘制
```python
detection_result = detector.detect(image)
boxes = detector.get_boxes(detection_result)
points = detector.get_points(detection_result)
# 直接使用位置数据,不绘制图像
for box in boxes:
print(f"Box: ({box['x1']}, {box['y1']}) -> ({box['x2']}, {box['y2']})")
for point in points:
print(f"Top: ({point['top_x']}, {point['top']})")
print(f"Bottom: ({point['bottom_x']}, {point['bottom']})")
```
## 点检测逻辑
根据检测到的类别组合,自动选择最佳检测方法:
1. **liquid_only**: 仅liquid → liquid最低点 + liquid最高点
2. **air_only**: 仅air → air最低点 + air最高点
3. **foam_only**: 仅foam → foam最低点 + foam最高点
4. **liquid_air**: liquid + air → liquid最低点 + air最高点
5. **liquid_foam**: liquid + foam → liquid最低点 + foam最高点
6. **liquid_foam_air**: liquid + foam + air → liquid最低点 + air最高点
7. **foam_air**: foam + air → foam最低点 + air最高点
## 兼容性
为保持向后兼容,提供了别名:
```python
AutoboxDetector = AutoAnnotationDetector
```
旧代码可以继续使用 `AutoboxDetector`
## 测试
运行测试函数:
```bash
python auto_dot.py
```
测试会自动:
1. 执行一次检测
2. 生成box标注并保存
3. 生成点标注并保存
4. 显示结果图像
# 自动标点功能模块使用说明
# 自动标点与自动选框功能模块使用说明
## 功能概述
`auto_dot.py` 模块实现了基于YOLO分割掩码的自动标点功能,可以自动检测容器的顶部和底部位置,替代人工手动标点。
`auto_dot.py` 模块实现了两个核心功能:
1. **AutoDotDetector**: 基于YOLO分割掩码的自动标点功能,自动检测容器的顶部和底部位置
2. **AutoboxDetector**: 自动选择标注区域功能,自动生成包含分割结果的最小面积box
## 核心特性
......@@ -153,14 +155,109 @@ if result['success']:
3. **调整检测框**: 如果检测失败,尝试调整检测框的位置和大小
4. **降低置信度**: 如果检测不到掩码,尝试降低 `conf_threshold`
## AutoboxDetector - 自动选框功能
### 功能说明
自动选择标注区域类,输入图像后自动生成包含分割结果的最小面积box。
### 核心特性
- **输入**: 图像
- **输出**: box位置数据 + 绘制完框的图像
- **box设置逻辑**:
1. 对每个类别(liquid、air、foam)的分割结果,合并同类别的所有mask
2. 计算每个类别mask的最小包围框
3. 支持设置最小面积阈值过滤小区域
4. 支持设置padding扩展box边界
### API 使用示例
```python
from handlers.videopage.auto_dot import AutoboxDetector
import cv2
# 1. 创建检测器
detector = AutoboxDetector(
model_path="path/to/model.dat",
device='cuda' # 或 'cpu'
)
# 2. 加载图片
image = cv2.imread("test_image.jpg")
# 3. 执行检测
result = detector.detect_boxes(
image=image,
conf_threshold=0.5, # 置信度阈值
min_area=100, # 最小面积阈值(像素)
padding=10 # box边界扩展像素数
)
# 4. 获取结果
if result['success']:
for box in result['boxes']:
print(f"类别: {box['class']}")
print(f"坐标: ({box['x1']}, {box['y1']}) -> ({box['x2']}, {box['y2']})")
print(f"面积: {box['area']}px²")
# 保存标注图片
cv2.imwrite("box_result.jpg", result['annotated_image'])
```
### 输出数据结构
```python
{
'success': bool, # 检测是否成功
'boxes': [
{
'x1': int, # 左上角x坐标
'y1': int, # 左上角y坐标
'x2': int, # 右下角x坐标
'y2': int, # 右下角y坐标
'class': str, # 类别名称 (liquid/air/foam)
'area': int # box面积(像素²)
},
...
],
'annotated_image': np.ndarray # 绘制完框的图像
}
```
### 可视化标注
标注图片包含:
- **绿色框**: liquid区域
- **蓝色框**: air区域
- **橙色框**: foam区域
- **类别标签**: 显示在框的左上角
### 独立测试
运行测试函数:
```bash
cd D:\restructure\liquid_level_line_detection_system\handlers\videopage
python auto_dot.py
```
测试函数会自动调用 `test_auto_box()`,输出结果保存在:
```
D:\restructure\liquid_level_line_detection_system\test_output\auto_box_result.jpg
```
## 接入系统
调试成功后,可以在主系统中调用:
```python
from handlers.videopage.auto_dot import AutoDotDetector
from handlers.videopage.auto_dot import AutoDotDetector, AutoboxDetector
# 方式1: 自动标点 - 在标注页面添加"自动标点"按钮
detector = AutoDotDetector(model_path="path/to/model.dat")
result = detector.detect_container_boundaries(image, conf_threshold=0.5)
# 在标注页面添加"自动标点"按钮
# 点击后调用 detector.detect_container_boundaries()
# 将返回的 top/bottom 坐标填充到标注点位置
# 方式2: 自动选框 - 在标注页面添加"自动选框"按钮
detector = AutoboxDetector(model_path="path/to/model.dat")
result = detector.detect_boxes(image, conf_threshold=0.5, min_area=100, padding=10)
```
......@@ -118,7 +118,7 @@ class TrainingWorker(QThread):
# 如果签名不匹配,说明这是一个直接重命名的 .pt 文件
if signature != MODEL_FILE_SIGNATURE:
print(f"[警告] {dat_path.name} 不是加密的 .dat 文件,将直接作为 .pt 文件使用")
# 直接返回原路径,YOLO 可以直接加载
# 直接返回原路径,模型 可以直接加载
return str(dat_path)
# 继续解密流程
......
1曲线模式索引0布局,只显示根据curvemission筛选使用的通道面板失效了
1曲线模式索引0布局,只显示根据curvemission筛选使用的通道面板失效了
......@@ -26,3 +26,37 @@
class ModelLoadingProgressDialog(QDialog):
"""模型加载进度条对话框"""
自动选择标注区域类
1.设置一个或多个最小面积box,box区域包含了某一区域的分割结果
自动标点,根据分割结果选择对应分支逻辑
1: liquid_only
- **容器底部**: liquid掩码的最低点
- **容器顶部**: liquid掩码的最高点
- **适用场景**: 只检测到液体,未检测到空气和泡沫
2: air_only
- **容器底部**: air掩码的最低点
- **容器顶部**: air掩码的最高点
- **适用场景**: 只检测到空气,未检测到液体和泡沫
3: foam_only
- **容器底部**: foam掩码的最低点
- **容器顶部**: foam掩码的最高点
- **适用场景**: 只检测到泡沫,未检测到液体和空气
4: liquid_air
- **容器底部**: liquid掩码的最低点
- **容器顶部**: air掩码的最高点
- **适用场景**: 同时检测到液体和空气,未检测到泡沫
5: liquid_foam
- **容器底部**: liquid掩码的最低点
- **容器顶部**: foam掩码的最高点
- **适用场景**: 同时检测到液体和泡沫,未检测到空气
6: liquid_foam_air
- **容器底部**: liquid掩码的最低点
- **容器顶部**: air掩码的最高点
- **适用场景**: 同时检测到液体、泡沫和空气
7: foam_air
- **容器底部**: foam掩码的最低点
- **容器顶部**: air掩码的最高点
- **适用场景**: 同时检测到泡沫和空气,未检测到液体
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment