''' lanhuage: python Descripttion: test xmls to json files. currently is just supported for labelImg and labelImgTool (https://github.com/lzx1413/LabelImgTool) version: beta Author: xiaoshuyui Date: 2020-09-24 09:41:23 LastEditors: xiaoshuyui LastEditTime: 2020-10-20 09:49:30 ''' import sys sys.path.append('..') import os from convertmask.utils.xml2json.xml2json import (getPolygon, x2jConvert, x2jConvert_pascal) BASE_DIR = os.path.abspath(os.path.dirname(os.getcwd())) + os.sep + 'static' if __name__ == "__main__": # getPolygon(BASE_DIR+os.sep+'bbox_label.xml') x2jConvert(BASE_DIR + os.sep + 'bbox_label.xml', BASE_DIR + os.sep + 'bbox_label.jpg') x2jConvert_pascal(BASE_DIR + os.sep + 'bbox_label.xml', BASE_DIR + os.sep + 'bbox_label.jpg')
def aug_labelimg(filepath, xmlpath, augs=None, num=0): default_augs = ['noise', 'rotation', 'trans', 'flip','zoom'] if augs is None: augs = ['noise', 'rotation', 'trans', 'flip','zoom'] # elif not isinstance(augs,list): else: if not isinstance(augs, list): try: augs = list(str(augs)) except: raise ValueError( "parameter:aug's type is wrong. expect a string or list,got {}" .format(str(type(augs)))) # else: augs = list(set(augs).intersection(set(default_augs))) if len(augs) > 0 and augs is not None: pass else: logger.warning( 'augumentation method is not supported.using default augumentation method.' ) augs = ['noise', 'rotation', 'trans', 'flip','zoom'] # l = np.random.randint(2,size=len(augs)).tolist() if 'flip' in augs: augs.remove('flip') augs.append('flip') l = np.random.randint(2, size=len(augs)) if np.sum(l) == 0: l[0] = 1 l[l != 1] = 1 l = l.tolist() # print(l) p = list(zip(augs, l)) img = filepath # processedImg = xmlpath jsonpath = x2jConvert_pascal(xmlpath, filepath) processedImg = jsonpath # logger.warning(processedImg) for i in p: # if i[0]!='flip': if i[1] == 1: if i[0] == 'noise': n = imgNoise(img, processedImg, flag=False) tmp = n['noise'] img, processedImg = tmp.oriImg, tmp.processedImg del n, tmp elif i[0] == 'rotation': angle = random.randint(-45, 45) r = imgRotation(img, processedImg, flag=False, angle=angle) tmp = r['rotation'] img, processedImg = tmp.oriImg, tmp.processedImg del r, tmp elif i[0] == 'trans': t = imgTranslation(img, processedImg, flag=False) tmp = t['trans'] img, processedImg = tmp.oriImg, tmp.processedImg del t, tmp elif i[0] == 'zoom': zoomFactor = random.uniform(0.8, 1.8) z = imgZoom(img,processedImg,zoomFactor,flag=False) tmp = z['zoom'] img = tmp.oriImg del z,tmp elif i[0] == 'flip': imgList = [] processedImgList = [] f = imgFlip(img, processedImg, flag=False) tmp = f['h_v'] imgList.append(tmp.oriImg) processedImgList.append(tmp.processedImg) tmp = f['h'] imgList.append(tmp.oriImg) processedImgList.append(tmp.processedImg) tmp = f['v'] imgList.append(tmp.oriImg) processedImgList.append(tmp.processedImg) img, processedImg = imgList, processedImgList del tmp, f, imgList, processedImgList parent_path = os.path.dirname(filepath) if os.path.exists(parent_path + os.sep + 'xmls_'): pass else: os.makedirs(parent_path + os.sep + 'xmls_') # fileName = jsonpath.split(os.sep)[-1].replace(".json", '') (_,fileName) = os.path.split(jsonpath) fileName = fileName.replace(".json", '') if isinstance(img, np.ndarray): io.imsave( parent_path + os.sep + 'xmls_' + os.sep + fileName + '_{}_assumble.jpg'.format(num), img) assumbleJson = getMultiShapes(parent_path + os.sep + 'xmls_' + os.sep + fileName + '_{}_assumble.jpg'.format(num), processedImg, flag=True, labelYamlPath='') saveJsonPath = parent_path + os.sep + 'xmls_' + os.sep + fileName + '_{}_assumble.json'.format( num) with open(saveJsonPath, 'w') as f: f.write(assumbleJson) j2xConvert(saveJsonPath) os.remove(saveJsonPath) print("Done!") print("see here {}".format(parent_path + os.sep + 'xmls_')) elif isinstance(img, list): for i in range(0, len(img)): io.imsave( parent_path + os.sep + 'xmls_' + os.sep + fileName + '_{}_assumble{}.jpg'.format(num, i), img[i]) assumbleJson = getMultiShapes(parent_path + os.sep + 'xmls_' + os.sep + fileName + '_{}_assumble{}.jpg'.format(num, i), processedImg[i], flag=True, labelYamlPath='') saveJsonPath = parent_path + os.sep + 'xmls_' + os.sep + fileName + '_{}_assumble{}.json'.format( num, i) with open(saveJsonPath, 'w') as f: f.write(assumbleJson) j2xConvert(saveJsonPath) os.remove(saveJsonPath) print("Done!") print("see here {}".format(parent_path + os.sep + 'xmls_'))
def script(): """ eg. argList = [('-l', '--labels', 'label files path','store_true')] """ argList = [ ('-n', '--nolabel', 'image augmentation without labels'), ('-H', '--HELP', 'show specific help informaton about supported method'), ('-X', '--labelImg', 'image augmentation for labelImg, default labelme. "X" for xml'), # ('--number', 'image augmentation numbers, default 1'), { 'shortName': '-N', 'fullName': '--number', 'type': int, 'help': 'image augmentation numbers, default 1' }, ('-L', '--nolog', 'remove "annoying" logs'), { 'shortName': '-c', 'fullName': '--classfilepath', 'type': str, 'help': 'class-information-path(for labelme is a *.yaml file,for labelImg is a *.txt file. without this file, this script has some errors when generate mask files and image augumentation.)' } ] p = Parser(argList, __appname__) parser = p.get_parser() args = vars(parser.parse_args()) # print(args) if args['version']: # print(1) from convertmask import __version__ print(__version__) del __version__ return if not args['method'] and not args['version']: parser.print_help() return if args['method'] and not args['input'] and not args['HELP']: logger.error('<=== INPUT FOLDER/FILE MUST NOT BE NULL ===>') return if args['nolog']: ccfg.setConfigParam(ccfg.cfp, 'log', 'show', 'False') if args['method'] not in __support_methods__ and args[ 'method'] not in supported_simplified_methods: # print(args['method']) kvs = getKV(__support_methods_simplified__) logger.warning(' only ==>{} are supported'.format('\n==>'.join(kvs))) lis = difflib.get_close_matches(args['method'], __support_methods__) # print(lis) if len(lis) > 0: logger.info('do you mean: {} ?'.format(' OR '.join(lis))) del lis return if args['method'] == 'mask2json' or args[ 'method'] == __support_methods_simplified__['mask2json']: if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print( ' origin-image-path(necessary), mask-image-path(necessary), yaml-file-path(can be blank,better dont)' ) print( ' origin images are used to generate base64 code. mask images are used to generate polygons. yaml file saves classes information' ) print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if len(params) < 2: raise MethodInputException('Not enough input parameters') elif len(params) == 2: inputOriimgPath = params[0] inputMaskPath = params[1] savePath = os.path.dirname(inputMaskPath) inputYamlPath = '' elif len(params) == 3: inputOriimgPath = params[0] inputMaskPath = params[1] savePath = os.path.dirname(inputMaskPath) inputYamlPath = params[2] else: raise MethodInputException('Too much input parameters') getJsons(inputOriimgPath, inputMaskPath, savePath, inputYamlPath) print('Done!') if args['method'] == 'mask2xml' or args[ 'method'] == __support_methods_simplified__['mask2xml']: if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print( ' origin-image-path(necessary), mask-image-path(necessary)') print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if len(params) < 2: raise MethodInputException('Not enough input parameters') elif len(params) == 2: inputOriimgPath = params[0] inputMaskPath = params[1] savePath = os.path.dirname(inputMaskPath) else: raise MethodInputException('Too much input parameters') getXmls(inputOriimgPath, inputMaskPath, savePath) print('Done!') if args['method'] == 'json2xml' or args[ 'method'] == __support_methods_simplified__['json2xml']: if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print(' json-file-path(necessary)') print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if len(params) < 1: raise MethodInputException('Not enough input parameters') elif len(params) == 1: inputJsonPath = params[0] else: raise MethodInputException('Too much input parameters') j2xConvert(inputJsonPath) print('Done!') if args['method'] == 'json2mask' or args[ 'method'] == __support_methods_simplified__['json2mask']: if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print(' json-file-path(necessary)') print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if len(params) < 1: raise MethodInputException('Not enough input parameters') elif len(params) == 1: inputJsonPath = params[0] else: raise MethodInputException('Too much input parameters') processor(inputJsonPath) print('Done!') if args['method'] == 'augmentation' or args[ 'method'] == __support_methods_simplified__['augmentation']: if not args['number']: number = 1 else: number = args['number'] if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print( ' origin-image-path(necessary), label-file-path(alternative).' ) print(' --nolabel can be added to just augment images.') print( ' --labelImg can be added to augment xmls, default jsons.') print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if args['classfilepath']: classFilePath = args['classfilepath'] else: classFilePath = '' if len(params) < 1: raise MethodInputException('Not enough input parameters') elif len(params) == 1 and args['nolabel']: inputFilePath = params[0] imgAug_withoutLabels(inputFilePath, number) print('Done!') elif len(params) == 2: inputFilePath = params[0] inputJsonPath = params[1] if not args['labelImg']: imgAug_withLabels(inputFilePath, inputJsonPath, number, yamlFilePath=classFilePath) else: imgAug_LabelImg(inputFilePath, inputJsonPath, number) print('Done!') else: raise MethodInputException('There must be some errors.') if args['method'] == 'xml2json' or args[ 'method'] == __support_methods_simplified__['xml2json']: logger.info('<=== This is a test function. ===>') if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print(' xml-file-path(necessary), origin-image-path(necessary)') print(' currently, only single file conversion supported.') print( ' --labelImg can be added which means xmls are generated by labelImg.' ) print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if len(params) < 2: raise MethodInputException('Not enough input parameters') elif len(params) == 2: inputFilePath = params[0] inputJsonPath = params[1] if not args['labelImg']: x2jConvert(inputFilePath, inputJsonPath) else: x2jConvert_pascal(inputFilePath, inputJsonPath) print('Done!') else: raise MethodInputException('Too much input parameters') if args['method'] == 'yolo2xml' or args[ 'method'] == __support_methods_simplified__['yolo2xml']: if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print( ' txt-file-path(necessary), origin-image-path(necessary), class-file-path(necessary' ) print(' currently, only single file conversion supported.') print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if len(params) < 3: raise MethodInputException('Not enough input parameters') elif len(params) == 3: txtpath = params[0] imgpath = params[1] labelPath = params[2] else: raise MethodInputException('Too much input parameters') y2xConvert(txtPath=txtpath, imgPath=imgpath, labelPath=labelPath) print('Done!') if args['method'] == 'xml2yolo' or args[ 'method'] == __support_methods_simplified__['xml2yolo']: if args['HELP']: print('\n') print("<==== {} detailed information ====>".format(args['method'])) print('\n') print('This method parameter list should follow this order.') print(' xml-file-path(necessary), class-file-path(alternative)') print( ' class-file is a txt file saves class information. without this file, a txt file will be generated automaticly, which may be in different orders' ) print('\n') print('<==== The End ====>') print('\n') else: params = args['input'] if len(params) < 1: raise MethodInputException('Not enough input parameters') elif len(params) == 1: xmlpath = params[0] x2yConvert(xmlpath) print('Done!') elif len(params) == 2: xmlpath = params[0] labelpath = params[1] x2yConvert(xmlpath, labelpath) print('Done!') else: raise MethodInputException('Too much input parameters')