Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/DOTA_devkit/ImgSplit.py
Views: 475
import os1import codecs2import numpy as np3import math4from dota_utils import GetFileFromThisRootDir5import cv26import shapely.geometry as shgeo7import dota_utils as util8import copy910def choose_best_pointorder_fit_another(poly1, poly2):11"""12To make the two polygons best fit with each point13"""14x1 = poly1[0]15y1 = poly1[1]16x2 = poly1[2]17y2 = poly1[3]18x3 = poly1[4]19y3 = poly1[5]20x4 = poly1[6]21y4 = poly1[7]22combinate = [np.array([x1, y1, x2, y2, x3, y3, x4, y4]), np.array([x2, y2, x3, y3, x4, y4, x1, y1]),23np.array([x3, y3, x4, y4, x1, y1, x2, y2]), np.array([x4, y4, x1, y1, x2, y2, x3, y3])]24dst_coordinate = np.array(poly2)25distances = np.array([np.sum((coord - dst_coordinate)**2) for coord in combinate])26sorted = distances.argsort()27return combinate[sorted[0]]2829def cal_line_length(point1, point2):30return math.sqrt( math.pow(point1[0] - point2[0], 2) + math.pow(point1[1] - point2[1], 2))313233class splitbase():34def __init__(self,35basepath,36outpath,37code = 'utf-8',38gap=100,39subsize=1024,40thresh=0.7,41choosebestpoint=True,42ext = '.png'43):44"""45:param basepath: base path for dota data46:param outpath: output base path for dota data,47the basepath and outputpath have the similar subdirectory, 'images' and 'labelTxt'48:param code: encodeing format of txt file49:param gap: overlap between two patches50:param subsize: subsize of patch51:param thresh: the thresh determine whether to keep the instance if the instance is cut down in the process of split52:param choosebestpoint: used to choose the first point for the53:param ext: ext for the image format54"""55self.basepath = basepath56self.outpath = outpath57self.code = code58self.gap = gap59self.subsize = subsize60self.slide = self.subsize - self.gap61self.thresh = thresh62self.imagepath = os.path.join(self.basepath, 'images')63self.labelpath = os.path.join(self.basepath, 'labelTxt')64self.outimagepath = os.path.join(self.outpath, 'images')65self.outlabelpath = os.path.join(self.outpath, 'labelTxt')66self.choosebestpoint = choosebestpoint67self.ext = ext68if not os.path.exists(self.outimagepath):69os.makedirs(self.outimagepath)70if not os.path.exists(self.outlabelpath):71os.makedirs(self.outlabelpath)7273## point: (x, y), rec: (xmin, ymin, xmax, ymax)74# def __del__(self):75# self.f_sub.close()76## grid --> (x, y) position of grids77def polyorig2sub(self, left, up, poly):78polyInsub = np.zeros(len(poly))79for i in range(int(len(poly)/2)):80polyInsub[i * 2] = int(poly[i * 2] - left)81polyInsub[i * 2 + 1] = int(poly[i * 2 + 1] - up)82return polyInsub8384def calchalf_iou(self, poly1, poly2):85"""86It is not the iou on usual, the iou is the value of intersection over poly187"""88inter_poly = poly1.intersection(poly2)89inter_area = inter_poly.area90poly1_area = poly1.area91half_iou = inter_area / poly1_area92return inter_poly, half_iou9394def saveimagepatches(self, img, subimgname, left, up):95subimg = copy.deepcopy(img[up: (up + self.subsize), left: (left + self.subsize)])96outdir = os.path.join(self.outimagepath, subimgname + self.ext)97cv2.imwrite(outdir, subimg)9899def GetPoly4FromPoly5(self, poly):100distances = [cal_line_length((poly[i * 2], poly[i * 2 + 1] ), (poly[(i + 1) * 2], poly[(i + 1) * 2 + 1])) for i in range(int(len(poly)/2 - 1))]101distances.append(cal_line_length((poly[0], poly[1]), (poly[8], poly[9])))102pos = np.array(distances).argsort()[0]103count = 0104outpoly = []105while count < 5:106#print('count:', count)107if (count == pos):108outpoly.append((poly[count * 2] + poly[(count * 2 + 2)%10])/2)109outpoly.append((poly[(count * 2 + 1)%10] + poly[(count * 2 + 3)%10])/2)110count = count + 1111elif (count == (pos + 1)%5):112count = count + 1113continue114115else:116outpoly.append(poly[count * 2])117outpoly.append(poly[count * 2 + 1])118count = count + 1119return outpoly120121def savepatches(self, resizeimg, objects, subimgname, left, up, right, down):122outdir = os.path.join(self.outlabelpath, subimgname + '.txt')123mask_poly = []124imgpoly = shgeo.Polygon([(left, up), (right, up), (right, down),125(left, down)])126with codecs.open(outdir, 'w', self.code) as f_out:127for obj in objects:128gtpoly = shgeo.Polygon([(obj['poly'][0], obj['poly'][1]),129(obj['poly'][2], obj['poly'][3]),130(obj['poly'][4], obj['poly'][5]),131(obj['poly'][6], obj['poly'][7])])132if (gtpoly.area <= 0):133continue134inter_poly, half_iou = self.calchalf_iou(gtpoly, imgpoly)135136# print('writing...')137if (half_iou == 1):138polyInsub = self.polyorig2sub(left, up, obj['poly'])139outline = ' '.join(list(map(str, polyInsub)))140outline = outline + ' ' + obj['name'] + ' ' + str(obj['difficult'])141f_out.write(outline + '\n')142elif (half_iou > 0):143#elif (half_iou > self.thresh):144## print('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')145inter_poly = shgeo.polygon.orient(inter_poly, sign=1)146out_poly = list(inter_poly.exterior.coords)[0: -1]147if len(out_poly) < 4:148continue149150out_poly2 = []151for i in range(len(out_poly)):152out_poly2.append(out_poly[i][0])153out_poly2.append(out_poly[i][1])154155if (len(out_poly) == 5):156#print('==========================')157out_poly2 = self.GetPoly4FromPoly5(out_poly2)158elif (len(out_poly) > 5):159"""160if the cut instance is a polygon with points more than 5, we do not handle it currently161"""162continue163if (self.choosebestpoint):164out_poly2 = choose_best_pointorder_fit_another(out_poly2, obj['poly'])165166polyInsub = self.polyorig2sub(left, up, out_poly2)167168for index, item in enumerate(polyInsub):169if (item <= 1):170polyInsub[index] = 1171elif (item >= self.subsize):172polyInsub[index] = self.subsize173outline = ' '.join(list(map(str, polyInsub)))174if (half_iou > self.thresh):175outline = outline + ' ' + obj['name'] + ' ' + str(obj['difficult'])176else:177## if the left part is too small, label as '2'178outline = outline + ' ' + obj['name'] + ' ' + '2'179f_out.write(outline + '\n')180#else:181# mask_poly.append(inter_poly)182self.saveimagepatches(resizeimg, subimgname, left, up)183184def SplitSingle(self, name, rate, extent):185"""186split a single image and ground truth187:param name: image name188:param rate: the resize scale for the image189:param extent: the image format190:return:191"""192img = cv2.imread(os.path.join(self.imagepath, name + extent))193if np.shape(img) == ():194return195fullname = os.path.join(self.labelpath, name + '.txt')196objects = util.parse_dota_poly2(fullname)197for obj in objects:198obj['poly'] = list(map(lambda x:rate*x, obj['poly']))199#obj['poly'] = list(map(lambda x: ([2 * y for y in x]), obj['poly']))200201if (rate != 1):202resizeimg = cv2.resize(img, None, fx=rate, fy=rate, interpolation = cv2.INTER_CUBIC)203else:204resizeimg = img205outbasename = name + '__' + str(rate) + '__'206weight = np.shape(resizeimg)[1]207height = np.shape(resizeimg)[0]208209left, up = 0, 0210while (left < weight):211if (left + self.subsize >= weight):212left = max(weight - self.subsize, 0)213up = 0214while (up < height):215if (up + self.subsize >= height):216up = max(height - self.subsize, 0)217right = min(left + self.subsize, weight - 1)218down = min(up + self.subsize, height - 1)219subimgname = outbasename + str(left) + '___' + str(up)220# self.f_sub.write(name + ' ' + subimgname + ' ' + str(left) + ' ' + str(up) + '\n')221self.savepatches(resizeimg, objects, subimgname, left, up, right, down)222if (up + self.subsize >= height):223break224else:225up = up + self.slide226if (left + self.subsize >= weight):227break228else:229left = left + self.slide230231def splitdata(self, rate):232"""233:param rate: resize rate before cut234"""235imagelist = GetFileFromThisRootDir(self.imagepath)236imagenames = [util.custombasename(x) for x in imagelist if (util.custombasename(x) != 'Thumbs')]237for name in imagenames:238self.SplitSingle(name, rate, self.ext)239240if __name__ == '__main__':241# example usage of ImgSplit242split = splitbase(r'example',243r'examplesplit')244split.splitdata(1)245246