添加 mutiple bounding boxes 顯示
This commit is contained in:
parent
706b5553fe
commit
89fcb4e6bb
6
.gitignore
vendored
6
.gitignore
vendored
@ -34,9 +34,9 @@ temp/
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
src/__pycache__/config.cpython-312.pyc
|
src/__pycache__/
|
||||||
src/services/__pycache__/device_service.cpython-312.pyc
|
src/services/__pycache__/
|
||||||
src/views/__pycache__/mainWindows.cpython-312.pyc
|
src/views/__pycache__/
|
||||||
main.spec
|
main.spec
|
||||||
dist/output/
|
dist/output/
|
||||||
dist/main.exe
|
dist/main.exe
|
||||||
|
|||||||
11
README.md
11
README.md
@ -209,4 +209,13 @@ global config 範例如下
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## bounding boxes 格式
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"num_boxes": 2,
|
||||||
|
"bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]],
|
||||||
|
"results": ["label1", "label2"]
|
||||||
|
}
|
||||||
|
```
|
||||||
@ -76,27 +76,23 @@ class MediaController:
|
|||||||
if hasattr(self.main_window, 'canvas_label'):
|
if hasattr(self.main_window, 'canvas_label'):
|
||||||
pixmap = QPixmap.fromImage(qt_image)
|
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)
|
painter = QPainter(pixmap)
|
||||||
pen = QPen(Qt.red)
|
pen = QPen(Qt.red)
|
||||||
pen.setWidth(2)
|
pen.setWidth(2)
|
||||||
painter.setPen(pen)
|
painter.setPen(pen)
|
||||||
|
|
||||||
# 獲取邊界框
|
# 遍歷並繪製所有邊界框
|
||||||
bbox_info = self.main_window.current_bounding_box
|
for bbox_info in self.main_window.current_bounding_boxes:
|
||||||
|
# 確保邊界框資訊是合法的
|
||||||
# 檢查邊界框格式
|
if isinstance(bbox_info, list) and len(bbox_info) >= 4:
|
||||||
if isinstance(bbox_info, dict) and "bounding box" in bbox_info:
|
|
||||||
# 從字典中獲取邊界框座標
|
|
||||||
bbox = bbox_info["bounding box"]
|
|
||||||
if len(bbox) >= 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))
|
painter.drawRect(QRect(x1, y1, x2 - x1, y2 - y1))
|
||||||
|
|
||||||
# 如果有結果標籤,繪製它
|
# 如果有標籤(邊界框的第5個元素),繪製它
|
||||||
if "result" in bbox_info:
|
if len(bbox_info) > 4 and bbox_info[4]:
|
||||||
font = QFont()
|
font = QFont()
|
||||||
font.setPointSize(10)
|
font.setPointSize(10)
|
||||||
painter.setFont(font)
|
painter.setFont(font)
|
||||||
@ -110,28 +106,7 @@ class MediaController:
|
|||||||
if label_y < 10:
|
if label_y < 10:
|
||||||
label_y = y2 + 15 # 如果上方空間不足,放在底部
|
label_y = y2 + 15 # 如果上方空間不足,放在底部
|
||||||
|
|
||||||
painter.drawText(label_x, label_y, bbox_info["result"])
|
painter.drawText(label_x, label_y, str(bbox_info[4]))
|
||||||
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.end()
|
painter.end()
|
||||||
|
|
||||||
@ -286,7 +261,7 @@ class MediaController:
|
|||||||
self._inference_paused = not self._inference_paused
|
self._inference_paused = not self._inference_paused
|
||||||
if self._inference_paused:
|
if self._inference_paused:
|
||||||
# 暫停時清除邊界框
|
# 暫停時清除邊界框
|
||||||
self.main_window.current_bounding_box = None
|
self.main_window.current_bounding_boxes = None
|
||||||
else:
|
else:
|
||||||
# 恢復推論時,確保相機仍在運行
|
# 恢復推論時,確保相機仍在運行
|
||||||
if self.video_thread is None or not self.video_thread.isRunning():
|
if self.video_thread is None or not self.video_thread.isRunning():
|
||||||
|
|||||||
Binary file not shown.
@ -30,7 +30,7 @@ class MainWindow(QWidget):
|
|||||||
|
|
||||||
# Set up UI and configuration
|
# Set up UI and configuration
|
||||||
self.destination = None
|
self.destination = None
|
||||||
self.current_bounding_box = None # 儲存當前的邊界框資訊
|
self.current_bounding_boxes = None # 儲存當前的邊界框資訊(改為複數形式)
|
||||||
self.generate_global_config()
|
self.generate_global_config()
|
||||||
self.init_ui()
|
self.init_ui()
|
||||||
|
|
||||||
@ -207,20 +207,46 @@ class MainWindow(QWidget):
|
|||||||
# 輸出結果到控制台
|
# 輸出結果到控制台
|
||||||
print("收到推論結果:", result)
|
print("收到推論結果:", result)
|
||||||
|
|
||||||
# 檢查結果是否包含邊界框資訊
|
# 檢查結果是否包含邊界框資訊(支持新舊兩種格式)
|
||||||
if isinstance(result, dict) and "bounding box" in 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:
|
if "result" in result:
|
||||||
# 將標籤添加為邊界框列表的第5個元素
|
# 確保邊界框列表至少有5個元素
|
||||||
if isinstance(self.current_bounding_box, list) and len(self.current_bounding_box) >= 4:
|
while len(self.current_bounding_boxes[0]) < 5:
|
||||||
# 確保邊界框列表至少有5個元素
|
self.current_bounding_boxes[0].append(None)
|
||||||
while len(self.current_bounding_box) < 5:
|
# 設置第5個元素為結果標籤
|
||||||
self.current_bounding_box.append(None)
|
self.current_bounding_boxes[0][4] = result["result"]
|
||||||
# 設置第5個元素為結果標籤
|
|
||||||
self.current_bounding_box[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
|
return
|
||||||
|
|||||||
@ -1,6 +1,22 @@
|
|||||||
### 0411
|
### 0410
|
||||||
1. 修改 repo 中的資料, 添加 .gitignore -> 0.5 hrs
|
1. 修改 repo 中的資料, 添加 .gitignore -> 0.5 hrs
|
||||||
2. 開會 meeting -> 1.5 hrs
|
2. 準備資料 + 開會 meeting -> 2 hrs
|
||||||
#### total: 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
|
||||||
Loading…
x
Reference in New Issue
Block a user