| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- import cv2
- import numpy as np
- from typing import List, Dict, Tuple, Union
- class ShapeDrawer:
- """形状绘制工具类"""
- @staticmethod
- def points_to_contour(points: List[List[int]]) -> np.ndarray:
- """
- 将点集转换为轮廓
- Args:
- points: 点集列表,每个点是 [x, y] 格式
- Returns:
- np.ndarray: OpenCV格式的轮廓
- """
- # 确保点集是整数类型的numpy数组
- contour = np.array(points, dtype=np.int32)
- # 重塑为OpenCV轮廓格式 (N, 1, 2)
- return contour.reshape((-1, 1, 2))
- @staticmethod
- def contour_to_mask(contour: np.ndarray,
- image_shape: Tuple[int, int]) -> np.ndarray:
- """
- 将轮廓转换为掩码
- Args:
- contour: OpenCV格式的轮廓
- image_shape: 图像形状 (height, width)
- Returns:
- np.ndarray: 二值掩码
- """
- # 创建空白掩码
- mask = np.zeros(image_shape, dtype=np.uint8)
- # 填充轮廓
- cv2.fillPoly(mask, [contour], 255)
- return mask
- @staticmethod
- def apply_mask_to_image(image: np.ndarray,
- mask: np.ndarray,
- color: Tuple[int, int, int],
- alpha: float = 0.5) -> np.ndarray:
- """
- 将掩码应用到图像上
- Args:
- image: 原始图像
- mask: 二值掩码
- color: BGR颜色
- alpha: 透明度
- Returns:
- np.ndarray: 带有掩码的图像
- """
- # 创建图像副本
- result = image.copy()
- # 创建彩色掩码
- color_mask = np.zeros_like(image)
- # color_mask[mask > 0] = color
- result[mask > 0] = color
- # 混合图像
- # cv2.addWeighted(color_mask, alpha, result, 1 - alpha, 0, result)
- return result
- @staticmethod
- def draw_shape_from_points(image: np.ndarray,
- points: List[List[int]],
- color: Tuple[int, int, int] = (0, 255, 0),
- alpha: float = 0.5,
- draw_contour: bool = True) -> np.ndarray:
- """
- 从点集绘制形状到图像上
- Args:
- image: 原始图像
- points: 点集列表
- color: BGR颜色
- alpha: 透明度
- draw_contour: 是否绘制轮廓线
- Returns:
- np.ndarray: 处理后的图像
- """
- # 1. 转换为轮廓
- contour = ShapeDrawer.points_to_contour(points)
- # 2. 创建掩码
- mask = ShapeDrawer.contour_to_mask(contour, image.shape[:2])
- # 3. 应用掩码
- result = ShapeDrawer.apply_mask_to_image(image, mask, color, alpha)
- # 4. 可选:绘制轮廓线
- if draw_contour:
- cv2.drawContours(result, [contour], -1, color, 2)
- return result
- def process_detection_result(image: np.ndarray,
- detection: Dict,
- label_colors: Dict
- ) -> np.ndarray:
- """
- 处理检测结果并在图像上绘制
- Args:
- image: 原始图像
- detection: 检测结果字典
- Returns:
- np.ndarray: 处理后的图像
- """
- result = image.copy()
- # 处理每个检测到的形状
- for shape in detection['shapes']:
- points = shape['points']
- label = shape['label']
- conf = shape['probability']
- # 获取颜色(默认绿色)
- color = label_colors.get(label, (0, 255, 0))
- # 绘制形状
- result = ShapeDrawer.draw_shape_from_points(
- result,
- points,
- color=color,
- alpha=0.3,
- draw_contour=True
- )
- # 添加标签和置信度
- first_point = points[0]
- is_print_text = False
- if is_print_text:
- cv2.putText(
- result,
- f"{label}: {conf:.2f}",
- (first_point[0], first_point[1] - 10),
- cv2.FONT_HERSHEY_SIMPLEX,
- 0.5,
- color,
- 2
- )
- return result
- # 示例使用
- if __name__ == "__main__":
- # 加载示例图像
- image = cv2.imread("example.jpg")
- # 为不同类别设置不同颜色
- label_colors = {
- 'baseboard': (0, 255, 0),
- }
- # 示例检测结果
- detection_result = {
- 'num': 1,
- 'cls': [1],
- 'names': ['baseboard'],
- 'conf': 0.9966249431977074,
- 'shapes': [{
- 'class_num': 1,
- 'label': 'baseboard',
- 'probability': 0.9966249431977074,
- 'points': [[5, 171], [4, 172], [0, 172], [0, 487], [34, 487],
- # ... 其他点 ...
- [1019, 172], [1018, 171]]
- }]
- }
- # 处理图像
- result = process_detection_result(image, detection_result,label_colors)
- # 显示结果
- cv2.imshow("Result", result)
- cv2.waitKey(0)
- cv2.destroyAllWindows()
- # 保存结果
- # cv2.imwrite("result.jpg", result)
|