crop.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import glob
  2. import json
  3. import os
  4. import shutil
  5. import random
  6. import cv2
  7. import numpy as np
  8. import base64
  9. import math
  10. import io
  11. import PIL.Image
  12. import os.path as osp
  13. import shapely
  14. from shapely.geometry import box, Polygon,MultiPolygon
  15. from shapely.geometry import Point
  16. def crop(src_path="d:/data/data_train_val_test",dst_path="d:/data/data_crop",win_width=640,win_height=640,step=320):
  17. if os.path.exists(dst_path):
  18. shutil.rmtree(dst_path)
  19. os.mkdir(dst_path)
  20. for phase in ["train","val"]:
  21. img_num=0
  22. if os.path.exists(dst_path+"/"+phase):
  23. shutil.rmtree(dst_path+"/"+phase)
  24. os.mkdir(dst_path+"/"+phase)
  25. f_phase=open(src_path+"/"+phase+".txt","r",encoding="utf-8")
  26. for line in f_phase.readlines():
  27. line=line.strip()
  28. ext = line.rsplit(".")[-1]
  29. len1 = len(line) - len(ext)
  30. json_f = line[:len1] + "json" #json文件
  31. basename = os.path.basename(line)
  32. bsname = basename.rsplit(".", 1)[0]
  33. parent = os.path.dirname(line)
  34. if os.path.exists(json_f):
  35. f_json=open(json_f,"rb")
  36. else:
  37. json_f2 = os.path.join(parent, "cor_" + bsname + ".json")
  38. if os.path.exists(json_f2):
  39. f_json=open(json_f2,"rb")
  40. #print("crop json_f: ",json_f2)
  41. #f_json=open(json_f,"rb")
  42. json_dict = json.load(f_json)
  43. # if img_bsname in ["201406300029"]:
  44. # continue
  45. img_ext=json_dict["imagePath"].rsplit(".",1)[-1]
  46. img=cv2.imread(line)
  47. big_h=json_dict["imageHeight"]
  48. big_w=json_dict["imageWidth"]
  49. for i in range(0,big_w,step):
  50. right_i = min(i + win_width, big_w)
  51. if right_i==i:
  52. continue
  53. for j in range(0,big_h,step):
  54. json_crop = {"version": "5.1.1", "flags": {}, "shapes": [], "imagePath": "", "imageHeight": 0,
  55. "imageWidth": 0,"imageData":""}
  56. bottom_j=min(j+win_height,big_h)
  57. if bottom_j == j:
  58. continue
  59. #crop_img=np.zeros([bottom_j-j,right_i-i,3])
  60. #crop_img = img[j:bottom_j,i:right_i,:]
  61. #按窗口大小裁剪小图,不够的地方用0填充。
  62. crop_img = np.zeros([win_height, win_width, 3],img.dtype)
  63. #print("j:bottom_j,i:right_i:", j,bottom_j,i,right_i,big_w,big_h)
  64. crop_img[:bottom_j-j,:right_i-i,:] = img[j:bottom_j,i:right_i,:]
  65. new_bsname=str(img_num)+"_"+str(i)+"_"+str(j)
  66. json_crop["imagePath"]=new_bsname+"."+img_ext
  67. json_crop["imageHeight"]=crop_img.shape[0]
  68. json_crop["imageWidth"]=crop_img.shape[1]
  69. dst_img_path=dst_path+"/"+phase+"/"+new_bsname+"."+img_ext
  70. dst_json_path = dst_path+"/"+phase+"/" + new_bsname + ".json"
  71. for shape in json_dict["shapes"]:
  72. ps=[]
  73. # for p in shape["points"]:
  74. # if p[0]>=i and p[0]<right_i and p[1]>=j and p[1]<bottom_j:
  75. # ps.append([p[0]-i,p[1]-j])
  76. #
  77. # if img_bsname in ["201406300015_0_0"]:
  78. # print("shape: ", shape)
  79. #如果是圆,就将圆转化为多边形
  80. if len(shape["points"])==2:
  81. #print("circle,dst_img_path:",dst_img_path)
  82. r=math.sqrt(math.pow(shape["points"][0][0]-shape["points"][1][0],2)+math.pow(shape["points"][0][1]-shape["points"][1][1],2))
  83. circle = Point(shape["points"][0]).buffer(r)
  84. try:
  85. poly1=Polygon(circle)
  86. except Exception as e:
  87. print("poly1 circle error: ", e)
  88. else:
  89. try:
  90. poly1=Polygon(shape["points"])
  91. except Exception as e:
  92. print("poly1 not circle error: ", e)
  93. # except:
  94. # print("poly1=Polygon(shape[points]) error")
  95. # print("dst_img_path,shape[points]: ", dst_img_path, shape["points"])
  96. # continue
  97. try:
  98. poly2= box(i,j,right_i,bottom_j)
  99. except Exception as e:
  100. print("poly2 error: ", e)
  101. try:
  102. intersection = poly1.intersection(poly2)
  103. except shapely.errors.GEOSException as e:
  104. print("shapely.errors.GEOSException error:",e)
  105. continue
  106. if intersection.is_empty:
  107. continue
  108. #长形装备会被拆分为多个
  109. if isinstance(intersection, MultiPolygon):
  110. pss = []
  111. #print("intersection type: ", intersection.type)
  112. #print("intersection:", len(intersection.geoms))
  113. for g in intersection.geoms:
  114. if (g.area < 10): #剔除面积太小的多边形
  115. continue
  116. pss.append(list(g.exterior.coords))
  117. for ps in pss:
  118. ps_new = []
  119. for p in ps:
  120. ps_new.append([p[0] - i, p[1] - j])
  121. shape_dict = {"points": ps_new, "group_id": shape["group_id"],"shape_type": "polygon", "flags": {}}
  122. if shape["label"] in ["white_crack","白色裂纹","白裂纹","白色裂缝","白裂缝","白色裂隙","白裂隙","balck_crack","black_crack","黑色裂纹","黑裂纹","黑色裂缝","黑裂缝","黑色裂隙","黑裂隙","crack","裂纹","裂缝","裂隙"]:
  123. label ="crack"
  124. shape_dict["label"]=label
  125. elif shape["label"] in ["white_hole","白色孔洞","白孔洞","black_hole","黑色孔洞","黑孔洞","hole","孔洞"]:
  126. label ="hole"
  127. shape_dict["label"] = label
  128. elif shape["label"] in ["white_debonding","白色脱粘","白脱粘","black_debonding","黑色脱粘","黑脱粘","debonding","脱粘"]:
  129. label ="debonding"
  130. shape_dict["label"] = label
  131. elif shape["label"] in ["rarefaction","疏松"]:
  132. label ="rarefaction"
  133. shape_dict["label"] = label
  134. else:
  135. pass
  136. if "label" in list(shape_dict.keys()):
  137. json_crop["shapes"].append(shape_dict)
  138. elif isinstance(intersection, Polygon):
  139. if(intersection.area<10):
  140. continue
  141. ps=(list(intersection.exterior.coords))
  142. ps_new = []
  143. for p in ps:
  144. ps_new.append([p[0] - i, p[1] - j])
  145. shape_dict = {"points": ps_new, "group_id": shape["group_id"], "shape_type": "polygon",
  146. "flags": {}}
  147. if shape["label"] in ["white_crack", "白色裂纹", "白裂纹", "白色裂缝", "白裂缝", "白色裂隙",
  148. "白裂隙", "balck_crack", "black_crack", "黑色裂纹", "黑裂纹",
  149. "黑色裂缝", "黑裂缝", "黑色裂隙", "黑裂隙", "crack", "裂纹", "裂缝",
  150. "裂隙"]:
  151. label = "crack"
  152. shape_dict["label"] = label
  153. elif shape["label"] in ["white_hole", "白色孔洞", "白孔洞", "black_hole", "黑色孔洞",
  154. "黑孔洞", "hole", "孔洞"]:
  155. label = "hole"
  156. shape_dict["label"] = label
  157. elif shape["label"] in ["white_debonding", "白色脱粘", "白脱粘", "black_debonding",
  158. "黑色脱粘", "黑脱粘", "debonding", "脱粘"]:
  159. label = "debonding"
  160. shape_dict["label"] = label
  161. elif shape["label"] in ["rarefaction", "疏松"]:
  162. label = "rarefaction"
  163. shape_dict["label"] = label
  164. else:
  165. pass
  166. if "label" in list(shape_dict.keys()):
  167. json_crop["shapes"].append(shape_dict)
  168. if len(json_crop["shapes"])>0: #只保存有目标的小图
  169. cv2.imwrite(dst_img_path, crop_img)
  170. def load_img(filename):
  171. # pillow读取tif图片出错,所以只能用opencv读取,再转为pillow
  172. # image_pil = PIL.Image.open(img_cv = cv2.imread(img_path)
  173. img_cv = cv2.imread(filename)
  174. image_pil = PIL.Image.fromarray(cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB))
  175. with io.BytesIO() as f:
  176. ext = osp.splitext(filename)[1].lower()
  177. if ext in [".jpg", ".jpeg"]:
  178. format = "JPEG"
  179. else:
  180. format = "PNG"
  181. image_pil.save(f, format=format)
  182. f.seek(0)
  183. return f.read()
  184. imageData = base64.b64encode(load_img(dst_img_path)).decode("utf-8")
  185. json_crop["imageData"] = imageData
  186. jsonOrderedFile = json.dumps(json_crop, ensure_ascii=False, indent=2)
  187. with open(dst_json_path, 'w') as jsonfile:
  188. jsonfile.write(jsonOrderedFile)
  189. f_json.close()
  190. img_num += 1
  191. f_phase.close()