handle_result.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import cv2
  2. import numpy as np
  3. from typing import List, Dict, Tuple
  4. class ShapeDrawer:
  5. """形状绘制工具类"""
  6. @staticmethod
  7. def points_to_contour(points: List[List[int]]) -> np.ndarray:
  8. """
  9. 将点集转换为轮廓
  10. Args:
  11. points: 点集列表,每个点是 [x, y] 格式
  12. Returns:
  13. np.ndarray: OpenCV格式的轮廓
  14. """
  15. # 确保点集是整数类型的numpy数组
  16. contour = np.array(points, dtype=np.int32)
  17. # 重塑为OpenCV轮廓格式 (N, 1, 2)
  18. return contour.reshape((-1, 1, 2))
  19. @staticmethod
  20. def contour_to_mask(contour: np.ndarray,
  21. image_shape: Tuple[int, int]) -> np.ndarray:
  22. """
  23. 将轮廓转换为掩码
  24. Args:
  25. contour: OpenCV格式的轮廓
  26. image_shape: 图像形状 (height, width)
  27. Returns:
  28. np.ndarray: 二值掩码
  29. """
  30. # 创建空白掩码
  31. mask = np.zeros(image_shape, dtype=np.uint8)
  32. # 填充轮廓
  33. cv2.fillPoly(mask, [contour], 255)
  34. return mask
  35. @staticmethod
  36. def apply_mask_to_image(image: np.ndarray,
  37. mask: np.ndarray,
  38. color: Tuple[int, int, int],
  39. alpha: float = 0.5) -> np.ndarray:
  40. """
  41. 将掩码应用到图像上
  42. Args:
  43. image: 原始图像
  44. mask: 二值掩码
  45. color: BGR颜色
  46. alpha: 透明度
  47. Returns:
  48. np.ndarray: 带有掩码的图像
  49. """
  50. # 创建图像副本
  51. result = image.copy()
  52. # 创建彩色掩码
  53. color_mask = np.zeros_like(image)
  54. # color_mask[mask > 0] = color
  55. result[mask > 0] = color
  56. # 混合图像
  57. # cv2.addWeighted(color_mask, alpha, result, 1 - alpha, 0, result)
  58. return result
  59. @staticmethod
  60. def draw_shape_from_points(image: np.ndarray,
  61. points: List[List[int]],
  62. color: Tuple[int, int, int] = (0, 255, 0),
  63. alpha: float = 0.5,
  64. draw_contour: bool = True) -> np.ndarray:
  65. """
  66. 从点集绘制形状到图像上
  67. Args:
  68. image: 原始图像
  69. points: 点集列表
  70. color: BGR颜色
  71. alpha: 透明度
  72. draw_contour: 是否绘制轮廓线
  73. Returns:
  74. np.ndarray: 处理后的图像
  75. """
  76. # 1. 转换为轮廓
  77. contour = ShapeDrawer.points_to_contour(points)
  78. # 2. 创建掩码
  79. mask = ShapeDrawer.contour_to_mask(contour, image.shape[:2])
  80. # 3. 应用掩码
  81. result = ShapeDrawer.apply_mask_to_image(image, mask, color, alpha)
  82. # 4. 可选:绘制轮廓线
  83. if draw_contour:
  84. cv2.drawContours(result, [contour], -1, color, 2)
  85. return result
  86. def process_detection_result(image: np.ndarray,
  87. detection: Dict,
  88. label_colors: Dict
  89. ) -> np.ndarray:
  90. """
  91. 处理检测结果并在图像上绘制
  92. Args:
  93. image: 原始图像
  94. detection: 检测结果字典
  95. Returns:
  96. np.ndarray: 处理后的图像
  97. """
  98. result = image.copy()
  99. # 处理每个检测到的形状
  100. for shape in detection['shapes']:
  101. points = shape['points']
  102. label = shape['label']
  103. conf = shape['probability']
  104. # 获取颜色(默认绿色)
  105. color = label_colors.get(label, (0, 255, 0))
  106. # 绘制形状
  107. result = ShapeDrawer.draw_shape_from_points(
  108. result,
  109. points,
  110. color=color,
  111. alpha=0.3,
  112. draw_contour=True
  113. )
  114. # 添加标签和置信度
  115. first_point = points[0]
  116. is_print_text = False
  117. if is_print_text:
  118. cv2.putText(
  119. result,
  120. f"{label}: {conf:.2f}",
  121. (first_point[0], first_point[1] - 10),
  122. cv2.FONT_HERSHEY_SIMPLEX,
  123. 0.5,
  124. color,
  125. 2
  126. )
  127. return result
  128. # 示例使用
  129. if __name__ == "__main__":
  130. # 加载示例图像
  131. image = cv2.imread("example.jpg")
  132. # 为不同类别设置不同颜色
  133. label_colors = {
  134. 'baseboard': (0, 255, 0),
  135. }
  136. # 示例检测结果
  137. detection_result = {
  138. 'num': 1,
  139. 'cls': [1],
  140. 'names': ['baseboard'],
  141. 'conf': 0.9966249431977074,
  142. 'shapes': [{
  143. 'class_num': 1,
  144. 'label': 'baseboard',
  145. 'probability': 0.9966249431977074,
  146. 'points': [[5, 171], [4, 172], [0, 172], [0, 487], [34, 487],
  147. # ... 其他点 ...
  148. [1019, 172], [1018, 171]]
  149. }]
  150. }
  151. # 处理图像
  152. result = process_detection_result(image, detection_result, label_colors)
  153. # 显示结果
  154. cv2.imshow("Result", result)
  155. cv2.waitKey(0)
  156. cv2.destroyAllWindows()
  157. # 保存结果
  158. # cv2.imwrite("result.jpg", result)