def dota2darknet(imgpath, txtpath, dstpath, extractclassname): """ :param imgpath: the path of images :param txtpath: the path of txt in dota format :param dstpath: the path of txt in YOLO format :param extractclassname: the category you selected :return: """ filelist = util.GetFileFromThisRootDir( txtpath) #解析dota标注类型的TXT路径,获取路径下所有的文件名,返回一个list for fullname in filelist: objects = util.parse_dota_poly(fullname) name = os.path.splitext(os.path.basename(fullname))[0] img_fullname = os.path.join(imgpath, name + '.png') img = Image.open(img_fullname) img_w, img_h = img.size # print img_w,img_h with open(os.path.join(dstpath, name + '.txt'), 'w') as f_out: for obj in objects: poly = obj['poly'] bbox = np.array(util.dots4ToRecC(poly, img_w, img_h)) if (sum(bbox <= 0) + sum(bbox >= 1)) >= 1: continue if (obj['name'] in extractclassname): id = extractclassname.index(obj['name']) else: continue outline = str(id) + ' ' + ' '.join(list(map(str, bbox))) f_out.write(outline + '\n')
def dota2darknet(imgpath, txtpath, dstpath, extractclassname): """ :param imgpath: the path of images :param txtpath: the path of txt in dota format :param dstpath: the path of txt in YOLO format :param extractclassname: the category you selected :return: """ objects = util.parse_dota_poly(txtpath) img = Image.open(imgpath) img_w, img_h = img.size # print img_w,img_h with open(dstpath, 'w') as f_out: for obj in objects: poly = obj['poly'] bbox = np.array(util.dots4ToRecC(poly, img_w, img_h)) if (sum(bbox <= 0) + sum(bbox >= 1)) >= 1: print('skipping {} (case 1)'.format(txtpath)) continue if (obj['name'] in extractclassname): id = extractclassname.index(obj['name']) else: print('skipping {} (case 2)'.format(txtpath)) continue outline = str(id) + ' ' + ' '.join(list(map(str, bbox))) f_out.write(outline + '\n')
def createIndex(self): for filename in self.imgpaths: objects = util.parse_dota_poly(filename) imgid = util.custombasename(filename) self.ImgToAnns[imgid] = objects for obj in objects: cat = obj['name'] self.catToImgs[cat].append(imgid)
def createIndex(self): for filename in self.imgpaths: objects = util.parse_dota_poly( filename ) # 返回 object列表,每个 obj 有 name difficult,poly ,area 四个属性 imgid = util.custombasename(filename) # 去掉后缀的文件路径 self.ImgToAnns[imgid] = objects # 给字典赋值 图像id到object的字典 for obj in objects: cat = obj['name'] self.catToImgs[cat].append(imgid) # 种类到图像id的字典
def dota2Darknet(imgpath, txtpath, dstpath, extractclassname): """ :param imgpath: the path of images :param txtpath: the path of txt in dota format :param dstpath: the path of txt in YOLO format :param extractclassname: the category you selected :return: txt format: id x y w h """ if os.path.exists(dstpath): shutil.rmtree(dstpath) # delete output folder os.makedirs(dstpath) # make new output folder filelist = util.GetFileFromThisRootDir( txtpath) # fileist=['/.../P0005.txt', ..., /.../P000?.txt] for fullname in filelist: # fullname='/.../P000?.txt' objects = util.parse_dota_poly(fullname) ''' objects = [{'name': 'ship', 'difficult': '1', 'poly': [(1054.0, 1028.0), (1063.0, 1011.0), (1111.0, 1040.0), (1112.0, 1062.0)], 'area': 1159.5 }, ... ] ''' name = os.path.splitext(os.path.basename(fullname))[0] # name='P000?' img_fullname = os.path.join(imgpath, name + '.png') # img_fullname='/.../P000?.png' img = Image.open(img_fullname) img_w, img_h = img.size # print img_w,img_h with open(os.path.join(dstpath, name + '.txt'), 'w') as f_out: for obj in objects: poly = obj['poly'] # poly=[(x1,y1),(x2,y2),(x3,y3),(x4,y4)] bbox = np.array(util.dots4ToRecC(poly, img_w, img_h)) # bbox=[x y w h] if (sum(bbox <= 0) + sum(bbox >= 1)) >= 1: # 若bbox中有<=0或>= 1的元素则将该box排除 continue if (obj['name'] in extractclassname): id = extractclassname.index( obj['name']) # id=类名的索引 比如'plane'对应id=0 else: continue outline = str(id) + ' ' + ' '.join(list(map( str, bbox))) # outline='id x y w h' f_out.write(outline + '\n') # 写入txt文件中并加上换行符号 \n
def extract_largesize_index(labelpath): filenames = util.GetFileFromThisRootDir(labelpath) large_size_index = [] for name in filenames: objs = util.parse_dota_poly(name) flag = 0 for obj in objs: poly = np.array(obj['poly']) xmin, ymin, xmax, ymax = np.min(poly[:, 0]), np.min(poly[:, 1]), np.max(poly[:, 0]), np.max(poly[:, 1]) w = xmax - xmin h = ymax - ymin max_side = max(w, h) if max_side > 400: flag = 1 break if flag: large_size_index.append(util.custombasename(name)) # print('index:', large_size_index) # print('len:', len(large_size_index)) return large_size_index
def dota2darknet(srcpath, dstpath, extractclassname): """ :param srcpath: the path of txt in dota format :param dstpath: the path of txt in YOLO format :param extractclassname: the category you selected :return: """ filelist = util.GetFileFromThisRootDir(srcpath) for fullname in filelist: objects = util.parse_dota_poly(fullname) name = os.path.splitext(os.path.basename(fullname))[0] with open(os.path.join(dstpath, name + '.txt'), 'w') as f_out: for obj in objects: poly = obj['poly'] bbox = np.array(util.dots4ToRecC(poly)) / 1024 if (sum(bbox <= 0) + sum(bbox >= 1)) >= 1: continue if (obj['name'] in extractclassname): id = extractclassname.index(obj['name']) else: continue outline = str(id) + ' ' + ' '.join(list(map(str, bbox))) f_out.write(outline + '\n')
def dota2LongSideFormat(imgpath, txtpath, dstpath, extractclassname): """ trans dota farmat to longside format :param imgpath: the path of images :param txtpath: the path of txt in dota format :param dstpath: the path of txt in YOLO format :param extractclassname: the category you selected """ if os.path.exists(dstpath): shutil.rmtree(dstpath) # delete output folder os.makedirs(dstpath) # make new output folder filelist = util.GetFileFromThisRootDir( txtpath) # fileist=['/.../P0005.txt', ..., /.../P000?.txt] for fullname in filelist: # fullname='/.../P000?.txt' objects = util.parse_dota_poly(fullname) ''' objects = [{'name': 'ship', 'difficult': '1', 'poly': [(1054.0, 1028.0), (1063.0, 1011.0), (1111.0, 1040.0), (1112.0, 1062.0)], 'area': 1159.5 }, ... ] ''' name = os.path.splitext(os.path.basename(fullname))[0] # name='P000?' img_fullname = os.path.join(imgpath, name + '.png') # img_fullname='/.../P000?.png' img = Image.open(img_fullname) img_w, img_h = img.size # print img_w,img_h with open(os.path.join(dstpath, name + '.txt'), 'w') as f_out: num_gt = 0 for i, obj in enumerate(objects): num_gt = num_gt + 1 # 为当前有效gt计数 poly = obj['poly'] # poly=[(x1,y1),(x2,y2),(x3,y3),(x4,y4)] poly = np.float32(np.array(poly)) # 四点坐标归一化 poly[:, 0] = poly[:, 0] / img_w poly[:, 1] = poly[:, 1] / img_h rect = cv2.minAreaRect(poly) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度) # box = np.float32(cv2.boxPoints(rect)) # 返回rect四个点的值 c_x = rect[0][0] c_y = rect[0][1] w = rect[1][0] h = rect[1][1] theta = rect[-1] # Range for angle is [-90,0) trans_data = cvminAreaRect2longsideformat( c_x, c_y, w, h, theta) if not trans_data: if theta != 90: # Θ=90说明wh中有为0的元素,即gt信息不完整,无需提示异常,直接删除 print('opencv表示法转长边表示法出现异常,已将第%d个box排除,问题出现在该图片中:%s' % (i, img_fullname)) num_gt = num_gt - 1 continue else: # range:[-180,0) c_x, c_y, longside, shortside, theta_longside = trans_data bbox = np.array((c_x, c_y, longside, shortside)) if (sum(bbox <= 0) + sum(bbox[:2] >= 1)) >= 1: # 0<xy<1, 0<side<=1 print( 'bbox[:2]中有>= 1的元素,bbox中有<= 0的元素,已将第%d个box排除,问题出现在该图片中:%s' % (i, img_fullname)) print( '出问题的longside形式数据:[%.16f, %.16f, %.16f, %.16f, %.1f]' % (c_x, c_y, longside, shortside, theta_longside)) num_gt = num_gt - 1 continue if (obj['name'] in extractclassname): id = extractclassname.index( obj['name']) # id=类名的索引 比如'plane'对应id=0 else: print('预定类别中没有类别:%s;已将该box排除,问题出现在该图片中:%s' % (obj['name'], fullname)) num_gt = num_gt - 1 continue theta_label = int(theta_longside + 180.5) # range int[0,180] 四舍五入 if theta_label == 180: # range int[0,179] theta_label = 179 # outline='id x y longside shortside Θ' # final check if id > 15 or id < 0: print('id problems,问题出现在该图片中:%s' % (i, img_fullname)) print( '出问题的longside形式数据:[%.16f, %.16f, %.16f, %.16f, %.1f]' % (c_x, c_y, longside, shortside, theta_longside)) if theta_label < 0 or theta_label > 179: print('id problems,问题出现在该图片中:%s' % (i, img_fullname)) print( '出问题的longside形式数据:[%.16f, %.16f, %.16f, %.16f, %.1f]' % (c_x, c_y, longside, shortside, theta_longside)) outline = str(id) + ' ' + ' '.join(list(map( str, bbox))) + ' ' + str(theta_label) f_out.write(outline + '\n') # 写入txt文件中并加上换行符号 \n if num_gt == 0: os.remove(os.path.join(dstpath, name + '.txt')) # os.remove(img_fullname) os.remove(fullname) print('%s 图片对应的txt不存在有效目标,已删除对应图片与txt' % img_fullname) print('已完成文件夹内DOTA数据形式到长边表示法的转换')