create_predict_result.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import numpy as np
  2. import cv2
  3. from pathlib import Path
  4. import time
  5. from app.utils.data_augmentation import LetterBox
  6. def point_mapTo_originImg(originImgSize, imgSize_train, now_point):
  7. letterBox = LetterBox(imgSize_train)
  8. rect_dict = letterBox.get_offset(originImgSize)
  9. x_ratio = originImgSize['width'] * 1.0 / rect_dict['width']
  10. y_ratio = originImgSize['height'] * 1.0 / rect_dict['height']
  11. new_y = round((now_point[1] - rect_dict['y']) * y_ratio)
  12. new_x = round((now_point[0] - rect_dict['x']) * x_ratio)
  13. new_point = [new_x, new_y]
  14. return new_point
  15. def create_result_singleImg(segClassDict, now_ansImgDict, originImgSize, imgSize_train, confidence=0.5):
  16. """ansImg_list.append({"ans_img":ansImg,"probs":probs,"file_name":file_name})"""
  17. label = now_ansImgDict['ans_img']
  18. probs = now_ansImgDict['probs']
  19. file_name = now_ansImgDict['file_name']
  20. # confidence = 0.5
  21. assert confidence > 0, "置信度必须大于0"
  22. # label[label < confidence] = 0
  23. per_result = {}
  24. per_result['num'] = 0
  25. per_result['cls'] = []
  26. per_result['names'] = []
  27. per_result['conf'] = []
  28. per_result['shapes'] = []
  29. # 背景肯定不需要提取
  30. excludeClassList = ['___background___']
  31. # 遍历每个分类
  32. for key, val in segClassDict.items():
  33. if val not in excludeClassList:
  34. now_class_num = int(key)
  35. now_prob_img = probs[now_class_num]
  36. # 10、将对应分类的图片弄白,其余全黑
  37. imgZero = np.zeros(label.shape, dtype=np.uint8)
  38. imgZero[label == (now_class_num)] = 255
  39. # 20、检测轮廓
  40. contours, _ = cv2.findContours(imgZero, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  41. # drawnContourImg = np.zeros((imgZero.shape[0], imgZero.shape[1], 3), dtype=np.uint8)
  42. # 把轮廓画出来了,可能label就是对应的轮廓
  43. # drawnContourImg = cv2.drawContours(drawnContourImg, contours, -1, (255, 0, 0), 2)
  44. # 30、获取shape数据
  45. if len(contours):
  46. maxCntArea = 5
  47. # 找最大轮廓面积对应的index
  48. for index in range(len(contours)):
  49. nowPntList = []
  50. # 面积
  51. contourArea = cv2.contourArea(contours[index])
  52. # 面积要大于5
  53. if contourArea > maxCntArea:
  54. # 计算置信度
  55. # 创建一个全为零的掩码图像,大小和原图像一样
  56. mask = np.zeros_like(imgZero)
  57. # 绘制第一个轮廓(假设我们只关心第一个轮廓)
  58. cv2.drawContours(mask, contours, index, (255), thickness=cv2.FILLED)
  59. # plt.imshow(now_prob_img, cmap='gray')
  60. # plt.show()
  61. # plt.imshow(mask, cmap='gray')
  62. # plt.show()
  63. # 计算轮廓区域的均值
  64. mean_val = cv2.mean(now_prob_img, mask=mask)
  65. now_conf = mean_val[0]
  66. externalContour = contours[index]
  67. pointNum = len(externalContour)
  68. # print(pointNum)
  69. for i in range(pointNum):
  70. nowPoint = externalContour[i]
  71. nowPoint_list = nowPoint[0].tolist()
  72. # 点要放到到原图上面
  73. new_point = point_mapTo_originImg(originImgSize, imgSize_train, nowPoint_list)
  74. nowPntList.append(new_point)
  75. pre_defect = {}
  76. pre_defect['class_num'] = int(key)
  77. pre_defect['label'] = str(val)
  78. pre_defect['probability'] = now_conf
  79. pre_defect['points'] = nowPntList
  80. if now_conf >= confidence:
  81. per_result['cls'].append(int(key))
  82. per_result['names'].append(str(val))
  83. per_result['conf'] = now_conf
  84. per_result['shapes'].append(pre_defect)
  85. per_result['num'] = len(per_result['shapes'])
  86. return per_result