predict3.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. # 并行计算
  2. import time
  3. import skimage
  4. from models.line_detect.postprocess import show_predict
  5. import os
  6. import torch
  7. from PIL import Image
  8. import matplotlib.pyplot as plt
  9. import matplotlib as mpl
  10. import numpy as np
  11. from models.line_detect.line_net import linenet_resnet50_fpn
  12. from torchvision import transforms
  13. # from models.wirenet.postprocess import postprocess
  14. from models.wirenet.postprocess import postprocess
  15. from rtree import index
  16. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  17. import multiprocessing as mp
  18. def process_box(box, lines, scores, idx):
  19. line_ = []
  20. score_ = []
  21. for i in box:
  22. score_max = 0.0
  23. tmp = [[0.0, 0.0], [0.0, 0.0]]
  24. # 获取与当前box可能相交的所有线段
  25. possible_matches = list(idx.intersection((i[0], i[1], i[2], i[3])))
  26. for j in possible_matches:
  27. line_j = lines[0, j].cpu().numpy() / 128 * 512
  28. if (line_j[0][0] >= i[0] and line_j[1][0] >= i[0] and
  29. line_j[0][0] <= i[2] and line_j[1][0] <= i[2] and
  30. line_j[0][1] >= i[1] and line_j[1][1] >= i[1] and
  31. line_j[0][1] <= i[3] and line_j[1][1] <= i[3]):
  32. if scores[j] > score_max:
  33. tmp = line_j
  34. score_max = scores[j]
  35. line_.append(tmp)
  36. score_.append(score_max)
  37. return torch.tensor(line_), torch.tensor(score_)
  38. def box_line_optimized1(pred):
  39. # 创建R-tree索引
  40. idx = index.Index()
  41. # 将所有线段添加到R-tree中
  42. lines = pred[-1]['wires']['lines'] # 形状为[1, 2500, 2, 2]
  43. scores = pred[-1]['wires']['score'][0] # 假设形状为[2500]
  44. for idx_line in range(lines.shape[1]): # 遍历2500条线段
  45. line_tensor = lines[0, idx_line].cpu().numpy() / 128 * 512 # 转换为numpy数组并调整比例
  46. x_min = float(min(line_tensor[0][0], line_tensor[1][0]))
  47. y_min = float(min(line_tensor[0][1], line_tensor[1][1]))
  48. x_max = float(max(line_tensor[0][0], line_tensor[1][0]))
  49. y_max = float(max(line_tensor[0][1], line_tensor[1][1]))
  50. idx.insert(idx_line, (max(0, x_min - 256), max(0, y_min - 256), min(512, x_max + 256), min(512, y_max + 256)))
  51. # 准备要处理的数据
  52. data_to_process = []
  53. for box_ in pred[0:-1]:
  54. box = box_['boxes'].cpu().numpy() # 确保将张量转换为numpy数组
  55. data_to_process.append((box, lines, scores, idx))
  56. # 使用 Pool 创建进程池并行处理数据
  57. with mp.Pool(processes=mp.cpu_count()) as pool: # 根据 CPU 核心数创建进程池
  58. results = pool.starmap(process_box, data_to_process)
  59. # 将结果放回原始 pred 中
  60. for idx_box, (processed_list, processed_s_list) in enumerate(results):
  61. pred[idx_box]['line'] = processed_list
  62. pred[idx_box]['line_score'] = processed_s_list
  63. return pred
  64. def load_best_model(model, save_path, device):
  65. if os.path.exists(save_path):
  66. checkpoint = torch.load(save_path, map_location=device)
  67. model.load_state_dict(checkpoint['model_state_dict'])
  68. # if optimizer is not None:
  69. # optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
  70. epoch = checkpoint['epoch']
  71. loss = checkpoint['loss']
  72. print(f"Loaded best model from {save_path} at epoch {epoch} with loss {loss:.4f}")
  73. else:
  74. print(f"No saved model found at {save_path}")
  75. return model
  76. def box_line_(pred):
  77. for idx, box_ in enumerate(pred[0:-1]):
  78. box = box_['boxes'] # 是一个tensor
  79. line = pred[-1]['wires']['lines'][idx].cpu().numpy() / 128 * 512
  80. score = pred[-1]['wires']['score'][idx]
  81. line_ = []
  82. score_ = []
  83. for i in box:
  84. score_max = 0.0
  85. tmp = [[0.0, 0.0], [0.0, 0.0]]
  86. for j in range(len(line)):
  87. if (line[j][0][1] >= i[0] and line[j][1][1] >= i[0] and
  88. line[j][0][1] <= i[2] and line[j][1][1] <= i[2] and
  89. line[j][0][0] >= i[1] and line[j][1][0] >= i[1] and
  90. line[j][0][0] <= i[3] and line[j][1][0] <= i[3]):
  91. if score[j] > score_max:
  92. tmp = line[j]
  93. score_max = score[j]
  94. line_.append(tmp)
  95. score_.append(score_max)
  96. processed_list = torch.tensor(line_)
  97. pred[idx]['line'] = processed_list
  98. processed_s_list = torch.tensor(score_)
  99. pred[idx]['line_score'] = processed_s_list
  100. return pred
  101. def box_line_optimized(pred):
  102. # 创建R-tree索引
  103. idx = index.Index()
  104. # 将所有线段添加到R-tree中
  105. lines = pred[-1]['wires']['lines'] # 形状为[1, 2500, 2, 2]
  106. scores = pred[-1]['wires']['score'][0] # 假设形状为[2500]
  107. # 提取并处理所有线段
  108. for idx_line in range(lines.shape[1]): # 遍历2500条线段
  109. line_tensor = lines[0, idx_line].cpu().numpy() / 128 * 512 # 转换为numpy数组并调整比例
  110. x_min = float(min(line_tensor[0][0], line_tensor[1][0]))
  111. y_min = float(min(line_tensor[0][1], line_tensor[1][1]))
  112. x_max = float(max(line_tensor[0][0], line_tensor[1][0]))
  113. y_max = float(max(line_tensor[0][1], line_tensor[1][1]))
  114. idx.insert(idx_line, (max(0, x_min - 256), max(0, y_min - 256), min(512, x_max + 256), min(512, y_max + 256)))
  115. for idx_box, box_ in enumerate(pred[0:-1]):
  116. box = box_['boxes'].cpu().numpy() # 确保将张量转换为numpy数组
  117. line_ = []
  118. score_ = []
  119. for i in box:
  120. score_max = 0.0
  121. tmp = [[0.0, 0.0], [0.0, 0.0]]
  122. # 获取与当前box可能相交的所有线段
  123. possible_matches = list(idx.intersection((i[0], i[1], i[2], i[3])))
  124. for j in possible_matches:
  125. line_j = lines[0, j].cpu().numpy() / 128 * 512
  126. if (line_j[0][1] >= i[0] and line_j[1][1] >= i[0] and # 注意这里交换了x和y
  127. line_j[0][1] <= i[2] and line_j[1][1] <= i[2] and
  128. line_j[0][0] >= i[1] and line_j[1][0] >= i[1] and
  129. line_j[0][0] <= i[3] and line_j[1][0] <= i[3]):
  130. if scores[j] > score_max:
  131. tmp = line_j
  132. score_max = scores[j]
  133. line_.append(tmp)
  134. score_.append(score_max)
  135. processed_list = torch.tensor(line_)
  136. pred[idx_box]['line'] = processed_list
  137. processed_s_list = torch.tensor(score_)
  138. pred[idx_box]['line_score'] = processed_s_list
  139. return pred
  140. def predict(pt_path, model, img):
  141. model = load_best_model(model, pt_path, device)
  142. model.eval()
  143. if isinstance(img, str):
  144. img = Image.open(img).convert("RGB")
  145. transform = transforms.ToTensor()
  146. img_tensor = transform(img) # [3, 512, 512]
  147. # 将图像调整为512x512大小
  148. im = img_tensor.permute(1, 2, 0) # [512, 512, 3]
  149. im_resized = skimage.transform.resize(im.cpu().numpy().astype(np.float32), (512, 512)) # (512, 512, 3)
  150. img_ = torch.tensor(im_resized).permute(2, 0, 1)
  151. with torch.no_grad():
  152. predictions = model([img_.to(device)])
  153. # print(predictions)
  154. pred = box_line_optimized1(predictions)
  155. # print(pred)
  156. # pred = box_line_(predictions)
  157. show_predict(img_, pred, t_start)
  158. if __name__ == '__main__':
  159. t_start = time.time()
  160. print(f'start to predict:{t_start}')
  161. model = linenet_resnet50_fpn().to(device)
  162. pt_path = r'D:\python\PycharmProjects\20250214\weight\resnet50_best_e100.pth'
  163. # img_path = f'D:\python\PycharmProjects\data2\images/train/2024-11-27-15-41-38_SaveImage.png' # 工件图
  164. # img_path = f'D:\python\PycharmProjects\data\images/train/00558656_3.png' # wireframe图
  165. img_path = r'C:\Users\m2337\Desktop\49.jpg'
  166. predict(pt_path, model, img_path)
  167. t_end = time.time()
  168. print(f'predict used:{t_end - t_start}')