diff --git a/.gitignore b/.gitignore index 4b296f3..660c7b1 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/README.md b/README.md index 6ca58db..718ddaa 100644 --- a/README.md +++ b/README.md @@ -209,4 +209,13 @@ global config 範例如下 } ] } -``` \ No newline at end of file +``` + +## bounding boxes 格式 + ``` + { + "num_boxes": 2, + "bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]], + "results": ["label1", "label2"] + } + ``` \ No newline at end of file diff --git a/src/controllers/media_controller.py b/src/controllers/media_controller.py index 5a1bae2..8b1076f 100644 --- a/src/controllers/media_controller.py +++ b/src/controllers/media_controller.py @@ -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(): diff --git a/src/views/__pycache__/mainWindows.cpython-312.pyc b/src/views/__pycache__/mainWindows.cpython-312.pyc deleted file mode 100644 index 7ef5507..0000000 Binary files a/src/views/__pycache__/mainWindows.cpython-312.pyc and /dev/null differ diff --git a/src/views/mainWindows.py b/src/views/mainWindows.py index a642e9d..7182757 100644 --- a/src/views/mainWindows.py +++ b/src/views/mainWindows.py @@ -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 diff --git a/update_diary.md b/update_diary.md index 5d897a7..30a83ba 100644 --- a/update_diary.md +++ b/update_diary.md @@ -1,6 +1,22 @@ -### 0411 +### 0410 1. 修改 repo 中的資料, 添加 .gitignore -> 0.5 hrs -2. 開會 meeting -> 1.5 hrs +2. 準備資料 + 開會 meeting -> 2 hrs #### total: 2 hrs --- -### \ No newline at end of file +### 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 \ No newline at end of file