添加 mutiple bounding boxes 顯示

This commit is contained in:
Mason Huang 2025-04-11 15:22:25 +08:00
parent 706b5553fe
commit 89fcb4e6bb
6 changed files with 80 additions and 54 deletions

6
.gitignore vendored
View File

@ -34,9 +34,9 @@ temp/
__pycache__/
*.py[cod]
*$py.class
src/__pycache__/config.cpython-312.pyc
src/services/__pycache__/device_service.cpython-312.pyc
src/views/__pycache__/mainWindows.cpython-312.pyc
src/__pycache__/
src/services/__pycache__/
src/views/__pycache__/
main.spec
dist/output/
dist/main.exe

View File

@ -210,3 +210,12 @@ global config 範例如下
]
}
```
## bounding boxes 格式
```
{
"num_boxes": 2,
"bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]],
"results": ["label1", "label2"]
}
```

View File

@ -76,27 +76,23 @@ class MediaController:
if hasattr(self.main_window, 'canvas_label'):
pixmap = QPixmap.fromImage(qt_image)
# 如果有邊界框,繪製它
if hasattr(self.main_window, 'current_bounding_box') and self.main_window.current_bounding_box is not None:
# 如果有邊界框,繪製它
if hasattr(self.main_window, 'current_bounding_boxes') and self.main_window.current_bounding_boxes is not None:
painter = QPainter(pixmap)
pen = QPen(Qt.red)
pen.setWidth(2)
painter.setPen(pen)
# 獲取邊界框
bbox_info = self.main_window.current_bounding_box
# 檢查邊界框格式
if isinstance(bbox_info, dict) and "bounding box" in bbox_info:
# 從字典中獲取邊界框座標
bbox = bbox_info["bounding box"]
if len(bbox) >= 4:
# 遍歷並繪製所有邊界框
for bbox_info in self.main_window.current_bounding_boxes:
# 確保邊界框資訊是合法的
if isinstance(bbox_info, list) and len(bbox_info) >= 4:
# 繪製矩形
x1, y1, x2, y2 = bbox[0], bbox[1], bbox[2], bbox[3]
x1, y1, x2, y2 = bbox_info[0], bbox_info[1], bbox_info[2], bbox_info[3]
painter.drawRect(QRect(x1, y1, x2 - x1, y2 - y1))
# 如果有結果標籤,繪製它
if "result" in bbox_info:
# 如果有標籤邊界框的第5個元素,繪製它
if len(bbox_info) > 4 and bbox_info[4]:
font = QFont()
font.setPointSize(10)
painter.setFont(font)
@ -110,28 +106,7 @@ class MediaController:
if label_y < 10:
label_y = y2 + 15 # 如果上方空間不足,放在底部
painter.drawText(label_x, label_y, bbox_info["result"])
elif isinstance(bbox_info, list) and len(bbox_info) >= 4:
# 直接使用列表作為邊界框座標
x1, y1, x2, y2 = bbox_info[0], bbox_info[1], bbox_info[2], bbox_info[3]
painter.drawRect(QRect(x1, y1, x2 - x1, y2 - y1))
# 如果有標籤,繪製它
if len(bbox_info) > 4 and bbox_info[4]:
font = QFont()
font.setPointSize(10)
painter.setFont(font)
painter.setPen(QColor(255, 0, 0)) # 紅色
# 計算標籤位置(邊界框上方)
label_x = x1
label_y = y1 - 10
# 確保標籤在畫布範圍內
if label_y < 10:
label_y = y2 + 15 # 如果上方空間不足,放在底部
painter.drawText(label_x, label_y, bbox_info[4])
painter.drawText(label_x, label_y, str(bbox_info[4]))
painter.end()
@ -286,7 +261,7 @@ class MediaController:
self._inference_paused = not self._inference_paused
if self._inference_paused:
# 暫停時清除邊界框
self.main_window.current_bounding_box = None
self.main_window.current_bounding_boxes = None
else:
# 恢復推論時,確保相機仍在運行
if self.video_thread is None or not self.video_thread.isRunning():

View File

@ -30,7 +30,7 @@ class MainWindow(QWidget):
# Set up UI and configuration
self.destination = None
self.current_bounding_box = None # 儲存當前的邊界框資訊
self.current_bounding_boxes = None # 儲存當前的邊界框資訊(改為複數形式)
self.generate_global_config()
self.init_ui()
@ -207,20 +207,46 @@ class MainWindow(QWidget):
# 輸出結果到控制台
print("收到推論結果:", result)
# 檢查結果是否包含邊界框資訊
# 檢查結果是否包含邊界框資訊(支持新舊兩種格式)
if isinstance(result, dict) and "bounding box" in result:
# 更新當前邊界框資訊
self.current_bounding_box = result["bounding box"]
# 舊格式兼容: 單一邊界框
self.current_bounding_boxes = [result["bounding box"]]
# 如果結果中有標籤,將其添加到邊界框中
if "result" in result:
# 將標籤添加為邊界框列表的第5個元素
if isinstance(self.current_bounding_box, list) and len(self.current_bounding_box) >= 4:
# 確保邊界框列表至少有5個元素
while len(self.current_bounding_box) < 5:
self.current_bounding_box.append(None)
# 設置第5個元素為結果標籤
self.current_bounding_box[4] = result["result"]
# 確保邊界框列表至少有5個元素
while len(self.current_bounding_boxes[0]) < 5:
self.current_bounding_boxes[0].append(None)
# 設置第5個元素為結果標籤
self.current_bounding_boxes[0][4] = result["result"]
# 不需要顯示彈窗,因為邊界框會直接繪製在畫面上
return
# 新格式: 多邊界框
elif isinstance(result, dict) and "bounding boxes" in result:
bboxes = result["bounding boxes"]
results = result.get("results", [])
# 確保邊界框是列表格式
if not isinstance(bboxes, list):
print("錯誤: 'bounding boxes' 必須是列表格式")
return
# 如果只有邊界框座標沒有標籤
if not results:
self.current_bounding_boxes = bboxes
else:
# 結合邊界框和標籤
self.current_bounding_boxes = []
for i, bbox in enumerate(bboxes):
# 創建包含座標的新列表
new_bbox = list(bbox)
# 添加標籤(如果有)
if i < len(results):
new_bbox.append(results[i])
else:
new_bbox.append(None)
self.current_bounding_boxes.append(new_bbox)
# 不需要顯示彈窗,因為邊界框會直接繪製在畫面上
return

View File

@ -1,6 +1,22 @@
### 0411
### 0410
1. 修改 repo 中的資料, 添加 .gitignore -> 0.5 hrs
2. 開會 meeting -> 1.5 hrs
2. 準備資料 + 開會 meeting -> 2 hrs
#### total: 2 hrs
---
###
### 0411
1. 解決 yolov5s 報錯: 將 input image 調整成 1500 * 1500 之後再把結果 mapping 回原先影像大小
```
Error code: 22. Description: ApiReturnCode KP_ERROR_IMAGE_RESOLUTION_TOO_SMALL_22
```
2. 修正 yolov5s 的回傳資料以符合 bounding box 顯示的格式
3. 添加 yolov5s classname mapping 機制
4. 添加 mutiple bounding boxes 顯示
```
{
"num_boxes": 2,
"bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]],
"results": ["label1", "label2"]
}
```
5. 更新 README.md: 添加 bounding boxes 的 return value