crop_patch.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # 根据标注文件,生成patch,每个类别放在一个文件夹下
  2. import os
  3. import sys
  4. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  5. import numpy as np
  6. import cv2
  7. import gc
  8. from dotenv import load_dotenv
  9. load_dotenv()
  10. # 从图像中截取patch_w*patch_h大小的图像,并打上标签
  11. patch_w = int(os.getenv('PATCH_WIDTH', 256))
  12. patch_h = int(os.getenv('PATCH_HEIGHT', 256))
  13. def main():
  14. # TODO:需要修改为标注好的图片路径
  15. input_path = r'D:\code\water_turbidity_det\frame_data\train\20260107\4_ch26_20260105141754'
  16. # TODO: 需要修改为保存patch的根目录
  17. output_path_root = r'D:\code\water_turbidity_det\label_data_tem\train'
  18. # 读取标注文件
  19. label_path = os.path.join(input_path, 'label.txt')
  20. if not os.path.exists(label_path): # 强制要求必须标注点什么
  21. raise FileNotFoundError(f"{label_path} 不存在")
  22. with open(label_path, 'r') as fr:
  23. lines = fr.readlines()
  24. lines = [line.strip() for line in lines]
  25. # 恢复标注的格网
  26. grids_info = [] # clicked_points
  27. for line in lines:
  28. point = line.split(',')
  29. grids_info.append([int(point[0]), int(point[1]), int(point[2]), int(point[3]), int(point[4])])
  30. # 我们先创建一些类别文件夹
  31. # 0类
  32. if not os.path.exists(os.path.join(output_path_root, str(0))):
  33. os.makedirs(os.path.join(output_path_root, str(0)))
  34. # 其余类
  35. for grid in grids_info:
  36. if grid[4] <= 0:
  37. continue
  38. if not os.path.exists(os.path.join(output_path_root, str(grid[4]))):
  39. os.makedirs(os.path.join(output_path_root, str(grid[4])))
  40. # 获取图像
  41. all_imgs = [os.path.join(input_path, i) for i in os.listdir(input_path) if i.split('.')[-1] == 'jpg' or i.split('.')[-1] == 'png']
  42. for img_path in all_imgs:
  43. img_base_name = os.path.basename(img_path).split('.')[0]
  44. img = cv2.imread(img_path)
  45. # 获取图像高宽
  46. img_h, img_w, _ = img.shape
  47. # 先将不参与训练的patch重置为0
  48. for g in grids_info:
  49. if g[4] < 0: # 标签小于零的不参与训练
  50. img[g[1]:min(g[1]+g[3], img_h), g[0]:min(g[0]+g[2], img_w), :] = 0
  51. # 再将大于0的patch保存到对应的类别文件夹下
  52. for g in grids_info:
  53. if g[4] > 0: # 标签大于零的放到相应的文件夹下
  54. patch_name = f'{os.path.basename(input_path)}_{img_base_name}_{g[0]}_{g[1]}_{g[4]}.jpg' # 图块保存名称:video名_图片名_左上角x_左上角y_类别.jpg
  55. patch = img[g[1]:min(g[1]+g[3], img_h), g[0]:min(g[0]+g[2], img_w), :]
  56. # 保存图块
  57. cv2.imwrite(os.path.join(output_path_root,str(g[4]), patch_name), patch)
  58. # 置零已经保存的patch区域
  59. img[g[1]:min(g[1]+g[3], img_h), g[0]:min(g[0]+g[2], img_w), :] = 0
  60. # 最后将剩余的patch保存到0类文件夹下
  61. for i in range(img_h // patch_h + 1):
  62. for j in range(img_w // patch_w + 1):
  63. patch = img[i*patch_h:min(i*patch_h+patch_h, img_h), j*patch_w:min(j*patch_w+patch_w, img_w), :]
  64. patch_name = f'{os.path.basename(input_path)}_{img_base_name}_{j*patch_w}_{i*patch_h}_0.jpg'
  65. # 长宽比过滤
  66. if patch.shape[0] / (patch.shape[1]+1e-6) > 1.314 or patch.shape[0] / (patch.shape[1]+1e-6) < 0.75:
  67. #print(f"长宽比过滤: {patch_name}")
  68. continue
  69. # 纯黑图像过滤
  70. if np.mean(patch) < 10.10:
  71. #print(f"纯黑图像过滤: {patch_name}")
  72. continue
  73. cv2.imwrite(os.path.join(output_path_root, '0', patch_name), patch)
  74. #print(f"保存图块: {patch_name}到{os.path.join(output_path_root, '0', patch_name)}")
  75. print(f"处理图片: {img_path}完成")
  76. # del patch, img
  77. # gc.collect()
  78. if __name__ == '__main__':
  79. main()