def zoom_img(src, zoomfactor): oriImgShape = src.shape w = oriImgShape[1] # width h = oriImgShape[0] # height resW = int(w * zoomfactor) resH = int(h * zoomfactor) zoomImg = cv2.resize(src, (resW, resH), cv2.INTER_AREA) zoomImgShape = zoomImg.shape if zoomfactor > 1: vDis = zoomImgShape[0] - oriImgShape[0] hDis = zoomImgShape[1] - oriImgShape[1] vDisHalf = int(vDis * 0.5) hDisHalf = int(hDis * 0.5) res = zoomImg[vDisHalf:zoomImgShape[0] + vDisHalf - vDis, hDisHalf:zoomImgShape[1] + hDisHalf - hDis] elif zoomfactor < 1: vDis = abs(zoomImgShape[0] - oriImgShape[0]) hDis = abs(zoomImgShape[1] - oriImgShape[1]) vDisHalf = int(vDis * 0.5) hDisHalf = int(hDis * 0.5) res = cv2.copyMakeBorder( zoomImg, vDisHalf, vDis - vDisHalf, hDisHalf, hDis - hDisHalf, cv2.BORDER_CONSTANT, ) else: logger.warning('zoomfactor is 1') res = src return res
def imgAug_LabelImg(imgPath, xmlpath, number=1): """ number : file number you want to generate. """ logger.info("currently, only *.jpg supported") oriImgs = glob.glob(imgPath + os.sep + '*.jpg') if os.path.isdir(imgPath) else [imgPath] xmlFiles = glob.glob(xmlpath + os.sep + '*.xml') if os.path.isdir(xmlpath) else [xmlpath] if type(number) != int: logger.error('Augumentation times error.Using 1 as default') number = 1 else: if number < 1: logger.warning( 'Augumentation times {} is less than 1.Using 1 as default'. format(number)) number = 1 pool = Pool(__CPUS__ - 1) pool_list = [] for i in oriImgs: for num in tqdm(range(0, number)): resultspool = pool.apply_async(proc_xml, (i, imgPath, xmlpath, num)) pool_list.append(resultspool) logger.info('successfully create {} tasks'.format(len(pool_list))) for pr in tqdm(pool_list): re_list = pr.get()
def convertImgSplit(oriImg: str, mask_or_xml: str, labelpath='', yamlPath: str = '', bias=2000): imgName = oriImg.split(os.sep)[-1][:-4] logger.warning("there is a issue related to Image Binarization") # logger.warning("this version is not convenient.it convert mask to json first because i \n have no idea how to modify getMultiShapes.py(getMultiObjs_voc)") if mask_or_xml.endswith('xml'): _, maskPath = x2m.x2mConvert(mask_or_xml, labelpath, yamlPath) maskImg = io.imread(maskPath) else: maskImg = mask_or_xml splitMaskImgList = splitImg_dengbili(reshape_dengbili(maskImg), bias=bias, savefile=False) splitMaskOriList = splitImg_dengbili(reshape_dengbili(io.imread(oriImg)), bias=bias, savefile=False) for i in range(0, len(splitMaskImgList)): tmpPath = save_ori_dir + os.sep + imgName + '_{}.jpg'.format(i) io.imsave(tmpPath, splitMaskOriList[i]) getMultiObjs_voc_withYaml(tmpPath, splitMaskImgList[i], yamlPath=yamlPath)
def getJsons(imgPath, maskPath, savePath, yamlPath=''): """ imgPath: origin image path \n maskPath : mask image path \n savePath : json file save path \n >>> getJsons(path-to-your-imgs,path-to-your-maskimgs,path-to-your-jsonfiles) """ logger.info("currently, only *.jpg supported") if os.path.isfile(imgPath): getMultiShapes.getMultiShapes(imgPath, maskPath, savePath, yamlPath) elif os.path.isdir(imgPath): oriImgs = glob.glob(imgPath + os.sep + '*.jpg') maskImgs = glob.glob(maskPath + os.sep + '*.jpg') for i in tqdm(oriImgs): i_mask = i.replace(imgPath, maskPath) if os.path.exists(i_mask): # print(i) getMultiShapes.getMultiShapes(i, i_mask, savePath, yamlPath) else: logger.warning('corresponding mask image not found!') continue else: logger.error( 'input error. got [{},{},{},{}]. file maybe missing.'.format( imgPath, maskPath, savePath, yamlPath)) logger.info('Done! See here. {}'.format(savePath))
def imgAug_withLabels(imgPath, labelPath, number=1, yamlFilePath=''): """ number : file number you want to generate. """ logger.info("currently, only *.jpg supported") oriImgs = glob.glob(imgPath + os.sep + '*.jpg') if os.path.isdir(imgPath) else [imgPath] jsonFiles = glob.glob(labelPath + os.sep + '*.json') if os.path.isdir(labelPath) else [ labelPath ] if type(number) != int: logger.error('Augumentation times error.Using 1 as default') number = 1 else: if number < 1: logger.warning( 'Augumentation times {} is less than 1.Using 1 as default'. format(number)) number = 1 for num in range(0, number): for i in tqdm(oriImgs): i_json = i.replace( imgPath, labelPath) if os.path.isdir(labelPath) else labelPath i_json = i_json.replace('.jpg', '.json') imgAug.aug_labelme(i, i_json, num=num, yamlFilePath=yamlFilePath)
def get_parser(self): self.parser.add_argument( 'method', metavar='PROCESS_METHOD', type=str, nargs='?', help='the method to be processed. currently, {} are supported.'. format(','.join(__support_methods__))) self.parser.add_argument('-v', '--version', help='show current version', action='store_true') self.parser.add_argument('-i', '--input', type=str, nargs='*', help='input files') if len(self.args) > 0: for i in self.args: self.add_parser(i) else: logger.warning('args list is null') return self.parser
def getMultiObjs_voc(oriImgPath, labelPath, savePath): # pass labelImg = io.imread(labelPath) # print(labelImg.shape) (_, fileName) = os.path.split(labelPath) # print(fileName) # fileName = labelPath.split(os.sep)[-1] imgShape = labelImg.shape imgHeight = imgShape[0] imgWidth = imgShape[1] imgPath = oriImgPath logger.warning("auto detecting class numbers") if len(imgShape) == 3: labelImg = labelImg[:, :, 0] labelImg[labelImg > 0] = 255 _, labels, stats, centroids = cv2.connectedComponentsWithStats( labelImg.astype(np.uint8)) statsShape = stats.shape objs = [] for i in range(1, statsShape[0]): st = stats[i, :] width = st[2] height = st[3] xmin = st[0] ymin = st[1] xmax = xmin + width ymax = ymin + height ob = {} ob['name'] = 'class{}'.format(i) ob['difficult'] = 0 # ob['name'] = 'weld' bndbox = {} bndbox['xmin'] = xmin bndbox['ymin'] = ymin bndbox['xmax'] = xmax bndbox['ymax'] = ymax ob['bndbox'] = bndbox objs.append(ob) saveXmlPath = savePath + os.sep + fileName[:-4] + '.xml' img2xml_multiobj(saveXmlPath, saveXmlPath, "TEST", fileName, imgPath, imgWidth, imgHeight, objs)
def imgZoom(oriImg, size, flag=True): """ size : The zoom factor along the axes, default 0.8~1.8 """ # pass if isinstance(oriImg, str): if os.path.exists(oriImg): img = io.imread(oriImg) else: raise FileNotFoundError('Original image not found') elif isinstance(oriImg, np.ndarray): img = oriImg else: logger.error('input {} type error'.format('oriImg')) return try: size = float(size) # if size == 0.0: # raise ValueError('zoom factor cannot be zero') except: logger.warning('input {} type error ,got {}.'.format( 'size', type(size))) size = random.uniform(0.8, 1.8) size = round(size, 2) if size <= 0 or size == 1: size = random.uniform(0.8, 1.8) size = round(size, 2) resOri = _getZoomedImg(img, size) if flag: parent_path = os.path.dirname(oriImg) if os.path.exists(parent_path + os.sep + 'augimgs_'): pass else: os.makedirs(parent_path + os.sep + 'augimgs_') tmp = os.path.splitext(oriImg)[0] fileName = tmp.split(os.sep)[-1] io.imsave( parent_path + os.sep + 'augimgs_' + os.sep + fileName + '_zoom.jpg', resOri) else: d = dict() d['zoom'] = Ori_Pro(resOri, None) return d
def __init__(self, img, heightFactor: float = 0.5, widthFactor: float = 0.5, getXmls: bool = False, xmls: list = [], savePath: str = ''): logger.warning( 'This script is not suitable for single image augumentation.') self.img = img self.heightFactor = heightFactor self.widthFactor = widthFactor self.getXmls = getXmls self.xmls = xmls self.savePath = savePath
def imgAug_withoutLabels(imgPath, number=1): logger.info("currently, only *.jpg supported") oriImgs = glob.glob(imgPath + os.sep + '*.jpg') if os.path.isdir(imgPath) else [imgPath] if type(number) != int: logger.error('Augumentation times error.Using 1 as default') number = 1 else: if number < 1: logger.warning( 'Augumentation times {} is less than 1.Using 1 as default'. format(number)) number = 1 for num in range(0, number): for i in tqdm(oriImgs): imgAug_nolabel.aug(i, num=num)
def getXmls(imgPath, maskPath, savePath): logger.info("currently, only *.jpg supported") if os.path.isfile(imgPath): getMultiShapes.getMultiObjs_voc(imgPath, maskPath, savePath) elif os.path.isdir(imgPath): oriImgs = glob.glob(imgPath + os.sep + '*.jpg') maskImgs = glob.glob(maskPath + os.sep + '*.jpg') for i in tqdm(oriImgs): i_mask = i.replace(imgPath, maskPath) # print(i) if os.path.exists(i_mask): getMultiShapes.getMultiObjs_voc(i, i_mask, savePath) else: logger.warning('corresponding mask image not found!') continue else: logger.error('input error. got [{},{},{}]. file maybe missing.'.format( imgPath, maskPath, savePath)) logger.info('Done! See here. {}'.format(savePath))
def x2yConvert(xmlpath, labelPath=''): labels = readLabels(labelPath) parent_path = os.path.dirname(xmlpath) if not os.path.exists(xmlpath): raise FileNotFoundError('file not found') else: if os.path.isfile(xmlpath): # pass logger.info('single file found') labels = readXmlSaveTxt(xmlpath, parent_path, labels) if len(labels) > 0: logger.warning('generate label file automaticly') with open(parent_path + os.sep + 'labels_.txt', 'w') as f: for i in labels: f.write(i + '\n') print('Done!') print("see here {}".format(parent_path)) else: xmls = glob.glob(xmlpath + os.sep + "*.xml") if not os.path.exists(parent_path + os.sep + 'txts_'): os.mkdir(parent_path + os.sep + 'txts_') logger.info('exists {} xml files'.format(len(xmls))) for xml in tqdm(xmls): labels = readXmlSaveTxt(xml, parent_path + os.sep + 'txts_', labels) if len(labels) > 0: logger.warning('generate label file automaticly') with open( parent_path + os.sep + 'txts_' + os.sep + 'labels_.txt', 'w') as f: for i in labels: f.write(i + '\n') logger.info('Done!') logger.info("see here {}".format(parent_path + os.sep + 'txts_'))
def writeXml(imgname, objlist, savepath, folder, name,oriImgPath=''): # imgname = lines[start].split('/')[-1] xmlname = imgname.replace('.jpg', '.xml').replace('\n', '') tmpPath = savepath + xmlname path = imgname if oriImgPath == '': logger.warning('Origin image needed!') width = 0 height = 0 else: oriImg = io.imread(oriImgPath+os.sep+imgname) width = oriImg.shape[1] height = oriImg.shape[0] del oriImg objs = [] # objlist = lines[start + 2:end] for ob in objlist: # print(ob) if len(ob) > 20: tmp = ob.split(' ') xmin = tmp[0] ymin = tmp[1] w = tmp[2] h = tmp[3] xmax = int(xmin) + int(w) ymax = int(ymin) + int(h) obj = dict() obj['name'] = name obj['diffcult'] = 0 bndbox = dict() bndbox['xmin'] = xmin bndbox['ymin'] = ymin bndbox['xmax'] = xmax bndbox['ymax'] = ymax obj['bndbox'] = bndbox objs.append(obj) img2xml_multiobj(tmpPath, tmpPath, folder, imgname, path, width, height, objs)
def aug_labelimg(filepath, xmlpath, augs=None, num=0, labelpath=''): 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 = processorWithLabel(jsonpath, labelpath, flag=True) if os.path.exists(labelpath): processedImg = processorWithLabel(jsonpath, labelpath, flag=True) else: processedImg = jsonpath # os.remove(jsonpath) for i in p: 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 if i[0] == 'rotation': angle = random.randint(-10, 10) 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, factor=0.1) 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, processedImg = tmp.oriImg, tmp.processedImg 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=labelpath) 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_')) # print("see here {}".format(saveJsonPath)) 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=labelpath) 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 imgZoom(oriImg: str, oriLabel: str, size: float = 0, flag=True, labelFile=''): """ size : The zoom factor along the axes, default 0.8~1.8 """ # pass if isinstance(oriImg, str): if os.path.exists(oriImg): img = io.imread(oriImg) else: raise FileNotFoundError('Original image not found') elif isinstance(oriImg, np.ndarray): img = oriImg else: logger.error('input {} type {} error'.format('oriImg', type(oriImg))) return try: size = float(size) # if size == 0.0: # raise ValueError('zoom factor cannot be zero') except: logger.warning('input {} type error ,got {}.'.format( 'size', type(size))) size = random.uniform(0.8, 1.8) size = round(size, 2) if size <= 0 or size == 1: size = random.uniform(0.8, 1.8) size = round(size, 2) resOri = _getZoomedImg(img, size) if isinstance(oriLabel, str): if os.path.exists(labelFile): # print(True) mask = processorWithLabel(oriLabel, labelFile, flag=True) else: mask = processor(oriLabel, flag=True) elif isinstance(oriLabel, np.ndarray): mask = oriLabel else: raise TypeError( "input parameter 'oriLabel' type {} is not supported".format( type(oriLabel))) maskImgs = _splitImg(mask) # print('========='+str(len(maskImgs))) resMask = np.zeros((resOri.shape[0], resOri.shape[1])) if len(maskImgs) > 0: for m in maskImgs: # print(np.max(m.img)) res = _getZoomedImg(m.img, size) res[res > 0] = m.clasId res[res != m.clasId] = 0 resMask += res # io.imsave('D:\\testALg\\mask2json\\mask2json\\static\\jsons_\\{}.png'.format(np.max(m.img)),resMask*255) resMask = resMask.astype(np.uint8) # io.imsave('D:\\testALg\\mask2json\\mask2json\\static\\jsons_\\12.png',resMask*255) # print(np.max(resMask)) if np.max(resMask) == 0: logger.warning( 'After zoom,none ROIs detected! Zoomfactor={} maybe too large.'. format(size)) # return if flag: parent_path = os.path.dirname(oriLabel) if os.path.exists(parent_path + os.sep + 'jsons_'): pass else: os.makedirs(parent_path + os.sep + 'jsons_') fileName = oriLabel.split(os.sep)[-1].replace('.json', '') io.imsave( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_zoom.jpg', resOri) zoomedMask_j = getMultiShapes(parent_path + os.sep + 'jsons_' + os.sep + fileName + '_zoom.jpg', resMask, flag=True, labelYamlPath=labelFile) saveJsonPath = parent_path + os.sep + 'jsons_' + os.sep + fileName + '_zoom.json' if zoomedMask_j is not None: with open(saveJsonPath, 'w') as f: f.write(zoomedMask_j) logger.info('Done! See {} .'.format( saveJsonPath)) if LOGFlag == 'True' else entity.do_nothing() else: pass else: d = dict() # print(resOri.shape) # io.imsave('D:\\testALg\\mask2json\\mask2json\\static\\jsons_\\13.png',resMask*255) d['zoom'] = Ori_Pro(resOri, resMask) return d
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'] 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)))) 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'] 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 ## For test l = l.tolist() p = list(zip(augs, l)) parent_path, file_name = os.path.split(filepath) filename, ext = os.path.splitext(file_name) if not os.path.exists(parent_path + os.sep + 'tmps_'): os.mkdir(parent_path + os.sep + 'tmps_') if not os.path.exists(parent_path + os.sep + 'augxmls_'): os.mkdir(parent_path + os.sep + 'augxmls_') labelPath = parent_path + os.sep + 'tmps_' + os.sep + filename + '_tmps.xml' shutil.copyfile(xmlpath, labelPath) img = io.imread(filepath) for i in p: if i[1] == 1: # if i[0] == 'test': # pass if i[0] == 'rotation': angle = random.randint(-10, 10) r = rotate(img, labelPath, angle) img, labelPath = r.oriImg, r.processedImg del r elif i[0] == 'trans': t = translation(img, labelPath) img, labelPath = t.oriImg, t.processedImg del t elif i[0] == 'zoom': z = zoom(img, labelPath) img, labelPath = z.oriImg, z.processedImg del z elif i[0] == 'noise': n = noise(img, labelPath) img, labelPath = n.oriImg, n.processedImg del n elif i[0] == 'flip': f = flip(img, labelPath) # img,labelPath = img = [] labelPath = [] for i in f: img.append(i.oriImg) labelPath.append(i.processedImg) del f if not isinstance(img, list): resXmlPath = parent_path + os.sep + 'augxmls_' + os.sep + filename + '_assumbel.xml' resImgPath = parent_path + os.sep + 'augxmls_' + os.sep + filename + '_assumbel.jpg' tree = ET.parse(labelPath) root = tree.getroot() root.find('folder').text = str(resImgPath.split(os.sep)[-1] if \ resImgPath.split(os.sep)[-1] != "" else resImgPath.split(os.sep)[-2] ) root.find('filename').text = filename + '_assumbel.jpg' root.find('path').text = resImgPath tree.write(resXmlPath) io.imsave(resImgPath, img) else: for i in range(0, len(img)): resXmlPath = parent_path + os.sep + 'augxmls_' + os.sep + filename + '_assumbel_{}.xml'.format( i) resImgPath = parent_path + os.sep + 'augxmls_' + os.sep + filename + '_assumbel_{}.jpg'.format( i) tree = ET.parse(labelPath[i]) root = tree.getroot() root.find('folder').text = str(resImgPath.split(os.sep)[-1] if \ resImgPath.split(os.sep)[-1] != "" else resImgPath.split(os.sep)[-2] ) root.find( 'filename').text = filename + '_assumbel_{}.jpg'.format(i) root.find('path').text = resImgPath tree.write(resXmlPath) io.imsave(resImgPath, img[i]) logger.info('Done! See {}.'.format(parent_path + os.sep + 'augxmls_'))
def imgFlip(oriImg: str, oriLabel: str, flip_list=[1, 0, -1], flag=True, labelFile=''): """ flipList: flip type. see cv2.flip : 1: 水平翻转 \n 0: 垂直翻转 \n -1: 同时翻转 \n >>> import cv2 >>> help(cv2.flip) """ if isinstance(oriImg, str): if os.path.exists(oriImg): img = io.imread(oriImg) else: raise FileNotFoundError('Original image not found') elif isinstance(oriImg, np.ndarray): img = oriImg else: logger.error('input {} type error'.format(imgFlip)) return try: if len(flip_list) > 1 and (1 in flip_list or 0 in flip_list or -1 in flip_list): if isinstance(oriLabel, str): if os.path.exists(labelFile): mask = processorWithLabel(oriLabel, labelFile, flag=True) else: mask = processor(oriLabel, flag=True) elif isinstance(oriLabel, np.ndarray): mask = oriLabel else: raise TypeError( "input parameter 'oriLabel' type is not supported") # print(type(mask)) h_ori = cv2.flip(img, 1) v_ori = cv2.flip(img, 0) h_v_ori = cv2.flip(img, -1) h_mask = cv2.flip(mask, 1) if 1 in flip_list else None v_mask = cv2.flip(mask, 0) if 0 in flip_list else None h_v_mask = cv2.flip(mask, -1) if -1 in flip_list else None """ maybe dict or zip is better :) """ if flag: parent_path = os.path.dirname(oriLabel) if os.path.exists(parent_path + os.sep + 'jsons_'): pass else: os.makedirs(parent_path + os.sep + 'jsons_') fileName = oriLabel.split(os.sep)[-1].replace('.json', '') io.imsave( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_h.jpg', h_ori) if 1 in flip_list else do_nothing() io.imsave( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_v.jpg', v_ori) if 0 in flip_list else do_nothing() io.imsave( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_h_v.jpg', h_v_ori) if -1 in flip_list else do_nothing() h_j = getMultiShapes( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_h.jpg', h_mask, flag=True, labelYamlPath='') if h_mask is not None else None # h_j = getMultiShapes(parent_path+os.sep+'jsons_'+os.sep+fileName+'_h.jpg',h_mask,flag=True,labelYamlPath='D:\\testALg\\mask2json\\mask2json\\multi_objs_json\\info.yaml') v_j = getMultiShapes( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_v.jpg', v_mask, flag=True, labelYamlPath='') if v_mask is not None else None h_v_j = getMultiShapes( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_h_v.jpg', h_v_mask, flag=True, labelYamlPath='') if h_v_mask is not None else None for saveJsonPath in [ parent_path + os.sep + 'jsons_' + os.sep + fileName + '_h.json', parent_path + os.sep + 'jsons_' + os.sep + fileName + '_v.json', parent_path + os.sep + 'jsons_' + os.sep + fileName + '_H_V.json' ]: # if saveJsonPath is not None: # print(saveJsonPath) if saveJsonPath.endswith('_h.json'): if h_j is not None: with open(saveJsonPath, 'w') as f: f.write(h_j) else: pass elif saveJsonPath.endswith('_v.json'): if v_j is not None: with open(saveJsonPath, 'w') as f: f.write(v_j) else: pass elif saveJsonPath.endswith('_H_V.json'): if h_v_j is not None: with open(saveJsonPath, 'w') as f: f.write(h_v_j) else: pass rmQ.rm(saveJsonPath) if os.path.exists( saveJsonPath) else do_nothing() return "" else: d = dict() d['h'] = Ori_Pro(h_ori, h_mask) d['v'] = Ori_Pro(v_ori, v_mask) d['h_v'] = Ori_Pro(h_v_ori, h_v_mask) return d else: logger.warning("<===== param:flip_list is not valid =====>") except Exception: # print(e) print(traceback.format_exc())
sys.path.append('..') from docopt import docopt from convertmask import __version__, baseDecorate from convertmask.utils.backup.cpFile import fileExist from convertmask.utils.imgAug_script import (imgAug_withLabels, imgAug_withoutLabels) from convertmask.utils.json2mask.convert import processor from convertmask.utils.json2xml.json2xml import j2xConvert from convertmask.utils.mask2json_script import getJsons, getXmls from convertmask.utils.methods.logger import logger if not fileExist(): logger.warning("connot find draw.py in labelme folder,which may cause some errors on labelme 4.2.9 (and maybe later). You can add it follow this step:https://github.com/guchengxi1994/mask2json#how-to-use") class MethodNotSupportException(Exception): pass @baseDecorate() def script(): arguments = docopt(__doc__) if arguments.get('--version') or arguments.get('-v'): print(__version__) elif arguments.get('m2j'): logger.info("Masks to jsons") print("<==== please input origin image path ====>")
def imgRotation(oriImg: str, oriLabel: str, angle=30, scale=1, flag=True, labelFile=''): """ 旋转 """ logger.warning( 'rotation may cause salt-and-pepper noise. in order to solve this issue, small objects may be missing!' ) if isinstance(oriImg, str): if os.path.exists(oriImg): img = io.imread(oriImg) else: raise FileNotFoundError('Original image not found') elif isinstance(oriImg, np.ndarray): img = oriImg else: logger.error('input {} type error'.format(imgFlip)) return imgShape = img.shape if isinstance(oriLabel, str): if os.path.exists(labelFile): mask = processorWithLabel(oriLabel, labelFile, flag=True) else: mask = processor(oriLabel, flag=True) elif isinstance(oriLabel, np.ndarray): mask = oriLabel else: raise TypeError( "input parameter 'oriLabel' type {} is not supported".format( type(oriLabel))) center = (0.5 * imgShape[1], 0.5 * imgShape[0]) mat = cv2.getRotationMatrix2D(center, angle, scale) affedImg = cv2.warpAffine(img, mat, (imgShape[1], imgShape[0])) affedMask = cv2.warpAffine(mask, mat, (imgShape[1], imgShape[0])) if flag: parent_path = os.path.dirname(oriLabel) if os.path.exists(parent_path + os.sep + 'jsons_'): pass else: os.makedirs(parent_path + os.sep + 'jsons_') fileName = oriLabel.split(os.sep)[-1].replace('.json', '') io.imsave( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_rotation.jpg', affedImg) affedMask_j = getMultiShapes(parent_path + os.sep + 'jsons_' + os.sep + fileName + '_rotation.jpg', affedMask, flag=True, labelYamlPath='') saveJsonPath = parent_path + os.sep + 'jsons_' + os.sep + fileName + '_rotation.json' if affedMask_j is not None: with open(saveJsonPath, 'w') as f: f.write(affedMask_j) else: pass else: d = dict() d['rotation'] = Ori_Pro(affedImg, affedMask) return d
def aug_labelme(filepath, jsonpath, augs=None, num=0, yamlFilePath=''): """ augs: ['flip','noise','affine','rotate','...'] """ 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() # l = [0, 0, 0, 1, 0] # for test p = list(zip(augs, l)) img = filepath # processedImg = jsonpath if os.path.exists(yamlFilePath): processedImg = processorWithLabel(jsonpath, yamlFilePath, flag=True) else: processedImg = jsonpath # print("======================={}".format(np.max(processedImg))) for i in p: # if i[0]!='flip': if i[1] == 1: if i[0] == 'noise': n = imgNoise(img, processedImg, flag=False, labelFile=yamlFilePath) 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, labelFile=yamlFilePath) tmp = r['rotation'] img, processedImg = tmp.oriImg, tmp.processedImg del r, tmp elif i[0] == 'trans': t = imgTranslation(img, processedImg, flag=False, labelFile=yamlFilePath) tmp = t['trans'] img, processedImg = tmp.oriImg, tmp.processedImg del t, tmp elif i[0] == 'zoom': zoomFactor = random.uniform(0.8, 1.8) # print("==========2============={}".format(np.max(processedImg))) z = imgZoom(img, processedImg, zoomFactor, flag=False, labelFile='') # print(type(z)) tmp = z['zoom'] img, processedImg = tmp.oriImg, tmp.processedImg del z, tmp elif i[0] == 'flip': imgList = [] processedImgList = [] f = imgFlip(img, processedImg, flag=False, labelFile=yamlFilePath) 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 + 'jsons_'): pass else: os.makedirs(parent_path + os.sep + 'jsons_') # fileName = jsonpath.split(os.sep)[-1].replace(".json", '') (_, fileName) = os.path.split(jsonpath) fileName = fileName.replace(".json", '') # io.imsave('D:\\testALg\\mask2json\\mask2json\\static\\jsons_\\12.png',processedImg*255) if isinstance(img, np.ndarray): io.imsave( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_{}_assumble.jpg'.format(num), img) assumbleJson = getMultiShapes(parent_path + os.sep + 'jsons_' + os.sep + fileName + '_{}_assumble.jpg'.format(num), processedImg, flag=True, labelYamlPath=yamlFilePath) saveJsonPath = parent_path + os.sep + 'jsons_' + os.sep + fileName + '_{}_assumble.json'.format( num) with open(saveJsonPath, 'w') as f: f.write(assumbleJson) print("Done!") print("see here {}".format(parent_path + os.sep + 'jsons_')) elif isinstance(img, list): for i in range(0, len(img)): io.imsave( parent_path + os.sep + 'jsons_' + os.sep + fileName + '_{}_assumble{}.jpg'.format(num, i), img[i]) assumbleJson = getMultiShapes(parent_path + os.sep + 'jsons_' + os.sep + fileName + '_{}_assumble{}.jpg'.format(num, i), processedImg[i], flag=True, labelYamlPath=yamlFilePath) saveJsonPath = parent_path + os.sep + 'jsons_' + os.sep + fileName + '_{}_assumble{}.json'.format( num, i) with open(saveJsonPath, 'w') as f: f.write(assumbleJson) print("Done!") print("see here {}".format(parent_path + os.sep + 'jsons_'))
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')