You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

AOI_get_box.py 5.8 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import cv2
  2. import os
  3. import numpy as np
  4. import shutil
  5. import argparse
  6. def parse_args():
  7. parser = argparse.ArgumentParser(description='get AOI class')
  8. parser.add_argument('--AOI_path', help='AOI path')
  9. parser.add_argument('--coco_path', help='coco path')
  10. parser.add_argument('--classes_file', help='classes file path')
  11. args = parser.parse_args()
  12. return args
  13. def setDir(filepath):
  14. '''
  15. 如果文件夹不存在就创建,如果文件存在就清空!
  16. :param filepath:需要创建的文件夹路径
  17. :return:
  18. '''
  19. if not os.path.exists(filepath):
  20. os.mkdir(filepath)
  21. else:
  22. shutil.rmtree(filepath,ignore_errors=True)
  23. # os.mkdir(filepath)
  24. args = parse_args()
  25. path = args.AOI_path+"/ng/"
  26. coco_path = args.coco_path
  27. coco_ann_path = args.coco_path+"/annotations/"
  28. coco_img_path = args.coco_path+"/images/"
  29. labels_path = args.coco_path+"/labels/"
  30. classes_file = args.classes_file
  31. setDir(coco_path)
  32. setDir(coco_ann_path)
  33. setDir(coco_img_path)
  34. setDir(labels_path)
  35. def order_points(pts):
  36. # pts为轮廓坐标
  37. # 列表中存储元素分别为左上角,右上角,右下角和左下角
  38. rect = np.zeros((4, 2), dtype = "float32")
  39. # 左上角的点具有最小的和,而右下角的点具有最大的和
  40. s = pts.sum(axis = 1)
  41. rect[0] = pts[np.argmin(s)]
  42. rect[2] = pts[np.argmax(s)]
  43. # 计算点之间的差值
  44. # 右上角的点具有最小的差值,
  45. # 左下角的点具有最大的差值
  46. diff = np.diff(pts, axis = 1)
  47. rect[1] = pts[np.argmin(diff)]
  48. rect[3] = pts[np.argmax(diff)]
  49. # 返回排序坐标(依次为左上右上右下左下)
  50. return rect
  51. def angle_cos(p0, p1, p2):
  52. d1, d2 = (p0-p1).astype('float'), (p2-p1).astype('float')
  53. return abs( np.dot(d1, d2) / np.sqrt( np.dot(d1, d1)*np.dot(d2, d2) ) )
  54. def cv_rename(file_path = ""):
  55. file_path_gbk = file_path.encode('gbk')
  56. return file_path_gbk.decode()
  57. imgs = os.listdir(path)
  58. i = 0
  59. class_AOI_name = {"bu_pi_pei":"1","fang_xiang_fan":"2","err.txt_c_not_f":"3"}
  60. class_name = {"yi_wei":"1","lou_jian":"2","ce_li":"3","li_bei":"4","shang_xia_fan_t":"5","lian_xi":"6","duo_jian":"7","sun_huai":"8","shao_xi":"9","jia_han":"10","yi_wu":"11",\
  61. "移位_Component_":"1","缺件_Component_":"2","侧立_Stand_Up":"3","立碑_Tombstone":"4","翻贴_Upside_Dow":"5","连锡_Solder_Bri":"6","Solderbridge":"6",\
  62. "损坏_Bad_Compon":"8","少锡_Insufficie":"9","假焊_Pseudo_Sol":"10", "qi_ta": "10"}
  63. count = 0
  64. count_qita = 0
  65. for img in imgs:
  66. i = i+1
  67. #print(img)
  68. img_name = img.split("@")
  69. #print(img_name[2], img_name[3])
  70. src = cv2.imdecode(np.fromfile(path+img, dtype=np.uint8), cv2.IMREAD_COLOR)# 默认的彩色图(IMREAD_COLOR)方式读入原始图像
  71. mask = cv2.imdecode(np.fromfile(path+img, dtype=np.uint8), 0) # 灰度图(IMREAD_GRAYSCALE)方式读入水印蒙版图像
  72. mask = np.where(mask<240, 239, mask)
  73. mask = (np.divide(mask-239, 16)*255)
  74. mask = np.where(mask<60, 0, mask)
  75. mask = np.uint8(mask)
  76. kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
  77. mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel,iterations=3)
  78. contours, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
  79. #print(contours)
  80. squares = []
  81. result = []
  82. k = 0
  83. for cnt in contours:
  84. cnt_len = cv2.arcLength(cnt, True) #计算轮廓周长
  85. #cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True) #多边形逼近
  86. # 条件判断逼近边的数量是否为4,轮廓面积是否大于1000,检测轮廓是否为凸的
  87. #print(len(cnt), cv2.contourArea(cnt), cv2.isContourConvex(cnt))
  88. if len(cnt) >= 4 and cv2.contourArea(cnt) > 30:
  89. #print("***********************")
  90. M = cv2.moments(cnt) #计算轮廓的矩
  91. cx = int(M['m10']/M['m00'])
  92. cy = int(M['m01']/M['m00'])#轮廓重心
  93. cnt = cnt.reshape(-1, 2)
  94. max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in range(4)])
  95. # 只检测矩形(cos90° = 0)
  96. #if max_cos < 0.3:
  97. # 检测四边形(不限定角度范围)
  98. if True:
  99. #index = index + 1
  100. #cv2.putText(img,("#%d"%index),(cx,cy),font,0.7,(255,0,255),2)
  101. if cv2.contourArea(cnt)>k:
  102. k = cv2.contourArea(cnt)
  103. result = cnt
  104. squares.append(cnt)
  105. mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
  106. try:
  107. rect = order_points(result)
  108. except:
  109. print(img)
  110. os.remove(path+img)
  111. continue
  112. #print(rect) # 获取最大内接矩形的4个顶点坐标
  113. x1 = 1000
  114. y1 = 1000
  115. x2 = 0
  116. y2 = 0
  117. for xy in rect:
  118. if x1>xy[0]:
  119. x1 = xy[0]
  120. if y1>xy[1]:
  121. y1 = xy[1]
  122. if x2<xy[0]:
  123. x2 = xy[0]
  124. if y2<xy[1]:
  125. y2 = xy[1]
  126. cv2.rectangle(src, (int(x1), int(y1)), (int(x2), int(y2)), (255, 255, 0), 3)
  127. label_result = img+" "+str(int(x1))+","+str(int(y1))+","+str(int(x2))+","+str(int(y2))+","+class_name[img_name[3]]
  128. #shutil.copy(path+img, coco_path+img)
  129. #print(img, img[:-4])
  130. path_file_name = labels_path+img[:-4]+".txt"
  131. if not os.path.exists(path_file_name):
  132. with open(path_file_name, "a") as f:
  133. f.write(label_result)
  134. #break
  135. print(class_name)
  136. print(count, count_qita)
  137. print("copying img")
  138. ok_path = args.AOI_path+"/ok/"
  139. ng_path = args.AOI_path+"/ng/"
  140. imgs = os.listdir(ok_path)
  141. for img in imgs:
  142. shutil.copy(ok_path+img, coco_img_path+img)
  143. imgs = os.listdir(ng_path)
  144. for img in imgs:
  145. shutil.copy(ng_path+img, coco_img_path+img)
  146. shutil.copy(classes_file, coco_path+"classes.txt")

No Description

Contributors (1)