def imgDistort(filepath: str, flag=True): if isinstance(filepath, str): if os.path.exists(filepath): img = io.imread(filepath) else: raise FileNotFoundError('Image file not found!') elif isinstance(filepath, np.ndarray): img = filepath else: logger.error('Input file error') return imgShape = img.shape imgWidth = imgShape[1] imgHeight = imgShape[0] center = (random.randint(int(0.2 * imgWidth), int(0.8 * imgWidth)), random.randint(int(0.2 * imgHeight), int(0.8 * imgHeight))) mouse = (random.randint(int(0.2 * imgWidth), int(0.8 * imgWidth)), random.randint(int(0.2 * imgHeight), int(0.8 * imgHeight))) radious = random.randint(50, 250) input_img = Image.fromarray(img).convert('RGB') resImg = imgFilter(input_img, radious, center, mouse) resImg = np.array(resImg) if flag: image_path, _ = os.path.splitext(filepath) io.imsave(image_path + '_distort.jpg', resImg) logger.info('Saved to {}'.format(image_path + '_distort.jpg')) else: return resImg
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 do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): if self.rect_or_poly == 'rect': return crop.multiRectanleCrop(self.img, self.cropNumber, self.noise) elif self.rect_or_poly == 'poly': return crop.multiPolygonCrop(self.img, self.cropNumber, self.noise, self.convexHull) else: res = [] for i in self.img: if self.rect_or_poly == 'rect': res.append( crop.multiRectanleCrop(i, self.cropNumber, self.noise)) elif self.rect_or_poly == 'poly': res.append( crop.multiPolygonCrop(i, self.cropNumber, self.noise, self.convexHull)) return res else: logger.error('Images are not found!')
def do(self): if len(self.augs) == 0: logger.info('None methods founds') return pimgs = self.imgs # print(pimgs) for i in self.operations: i.setImgs(pimgs) pimgs = i.do() gc.collect() if not self.saveFile: return pimgs else: if not os.path.exists(self.saveDir) and self.saveDir != '': os.mkdir(self.saveDir) else: logger.error("Provided savedir is not valid") return if type(self.imgs) is not list: if type(self.imgs) is str: filename = os.path.split(self.imgs)[1] else: filename = 'test.jpg' io.imsave(self.saveDir + os.sep + filename, pimgs) else: for i in range(len(self.imgs)): if isinstance(self.augs[i], str): filename = os.path.split(i)[1] else: filename = 'test{}.jpg'.format(i) io.imsave(self.saveDir + os.sep + filename, pimgs[i]) logger.info("Done! See {}.".format(self.saveDir))
def readYamlFile(yamlFile): if isinstance(yamlFile, str) and os.path.exists(yamlFile): if yamlFile.endswith('.yaml'): f = open(yamlFile, 'r', encoding='utf-8') x = yaml.load(f.read(), Loader=yaml.FullLoader) try: res = x['label_names'] return res except: return None finally: f.close() elif yamlFile.endswith('.txt'): with open(yamlFile, 'r', encoding='utf-8') as f: classList = f.readlines() res = labels2yaml(classList, savefile=False) return res['label_names'] elif isinstance(yamlFile, dict): try: res = x['label_names'] return res except: return None else: logger.error( 'input type error. must be a .txt file or .yaml file or a dict like \{"label_names":["classA":1,...,"classN":10]\}' )
def labels2yaml(labels: list, savePath='', savefile=True): # pass if '_background_' not in labels: labels.append('_background_') tmp = dict() tmp['_background_'] = 0 classId = 1 for i in range(0, len(labels)): x = labels[i].replace('\n','').strip() if x != '_background_': tmp[x] = classId classId += 1 data = dict() data['label_names'] = tmp del tmp if savefile: try: with open(savePath + os.sep + 'info.yaml', 'w', encoding='utf-8') as f: yaml.dump(data, f, allow_unicode=True) logger.info("successfully convert labels to yaml, see {}".format( savePath + os.sep + 'info.yaml')) except Exception as e: logger.error(e) return data
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 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 load(stream, Loader=None): if isinstance(stream, str): lis = readYamlFile(stream) elif isinstance(stream, _io.TextIOWrapper): lis = stream.readlines() else: logger.error('input parameter error.') return res = dict() sections, secNameNum, secNum = getSection(lis)
def readYamlFile(filepath: str, encoding='utf-8'): if not os.path.exists(filepath): logger.error('file not found') return with open(filepath, 'r', encoding=encoding) as f: # print(type(f)) lis = f.readlines() # print(lis) return lis
def do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): return distort.imgDistort(self.img, flag=False) else: res = [] for i in self.img: res.append(distort.imgDistort(i, flag=False)) return res else: logger.error('Images are not found!')
def do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): return imgZoom(self.img, self.size, False).get('zoom').oriImg else: res = [] for i in self.img: res.append(imgZoom(i, 1.0, False).get('zoom').oriImg) return res else: logger.error('Images are not found!')
def do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): return perspective.persTrans(self.img, self.factor) else: res = [] for i in self.img: res.append(perspective.persTrans(i, self.factor)) return res else: logger.error('Images are not found!')
def do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): return imgNoise(self.img, False, self.noiseType).get('noise').oriImg else: res = [] for i in self.img: res.append(imgNoise(i, False, []).get('noise').oriImg) return res else: logger.error('Images are not found!')
def do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): return imgTranslation(self.img, False, self.th, self.tv).get('trans').oriImg else: res = [] for i in self.img: res.append( imgTranslation(i, False, 0, 0).get('trans').oriImg) return res else: logger.error('Images are not found!')
def go(self, **kwargs): if not os.path.exists(self.img_or_path) or not os.path.exists( self.label_or_path): logger.error('File or path not exists!') return # single file if os.path.isfile(self.label_or_path): # xml format _, filename = os.path.split(self.label_or_path) if self.saveFilePath == '': savePath = self.label_or_path else: savePath = self.saveFilePath + os.sep + filename go_single(self.label_or_path, self.img_or_path, self.negativeNumbers, self.iou, self.negativeClassName, savePath) else: xmls = glob.glob(self.label_or_path + os.sep + '*.xml') if not self.multiProcesses: for i in tqdm(xmls): _, filename = os.path.split(i) if self.saveFilePath == '': savePath = self.label_or_path else: savePath = self.saveFilePath + os.sep + filename imgpath = self.img_or_path + os.sep + filename.replace( '.xml', '.jpg') go_single(i, imgpath, self.negativeNumbers, self.iou, self.negativeClassName, savePath) else: pool = Pool(__CPUS__ - 1) pool_list = [] for i in xmls: _, filename = os.path.split(i) if self.saveFilePath == '': savePath = self.label_or_path else: savePath = self.saveFilePath + os.sep + filename imgpath = self.img_or_path + os.sep + filename.replace( '.xml', '.jpg') resultspool = pool.apply_async( go_single, (i, imgpath, self.negativeNumbers, self.iou, self.negativeClassName, savePath)) pool_list.append(resultspool) for pr in tqdm(pool_list): re_list = pr.get()
def do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): return imgRotation(self.img, self.angle, self.scale, False).get('rotation').oriImg else: res = [] for i in self.img: res.append( imgRotation(i, self.angle, self.scale, False).get('rotation').oriImg) return res else: logger.error('Images are not found!')
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 do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): if self.rect_or_poly == 'rect': return inpaint.rectangleInpaint(self.img, self.startPoint) elif self.rect_or_poly == 'poly': return inpaint.polygonInpaint(self.img, self.startPoint) else: res = [] for i in self.img: res.append(inpaint.polygonInpaint(i, self.startPoint)) return res else: logger.error('Images are not found!')
def getPolygonPascal(xmlPath): in_file = open(xmlPath) tree = ET.parse(in_file) root = tree.getroot() shapes = [] try: for obj in root.iter('object'): flags = {} group_id = 'null' shape_type = 'polygon' # pass dic = dict() label = obj.find('name').text polygon = obj.find('bndbox') # print(len(polygon)) # if len(polygon)>2: # points = [] # for i in range(0,len(polygon)): xmin = int(polygon.find('xmin').text) ymin = int(polygon.find('ymin').text) xmax = int(polygon.find('xmax').text) ymax = int(polygon.find('ymax').text) # print(polygon.find('point{}'.format(i)).text) # tmp = polygon.find('point{}'.format(i)).text.split(',') # point = [int(tmp[0]),int(tmp[1])] # print(point) p1 = [xmin, ymin] p2 = [xmax, ymax] p3 = [xmin, ymax] p4 = [xmax, ymin] # points.append(point) points = [p1, p2, p3, p4] # del tmp,point dic['flags'] = flags dic['group_id'] = group_id dic['shape_type'] = shape_type dic['points'] = points dic['label'] = label shapes.append(dic) # print(shapes) return shapes except Exception: logger.error(traceback.print_exc())
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 mosiac_img(imgs: list, heightFactor=0.5, widthFactor=0.5): if not type(imgs) is list: logger.error('Input must be a list!') return if len(imgs) == 0: logger.error('None image found!') return if len(imgs) == 1: for _ in range(0, 3): imgs.append(imgs[0]) if len(imgs) == 2: for _ in range(0, 2): imgs.append(imgs[0]) if len(imgs) == 3: for _ in range(0, 1): imgs.append(imgs[0]) mHeight, mWidth = getMeanSize(imgs) img_left_top = resize_img( np.array(skimage.transform.resize(imgs[0], (mHeight, mWidth)) * 255).astype(np.uint8), heightFactor, widthFactor) img_right_top = resize_img( np.array(skimage.transform.resize(imgs[1], (mHeight, mWidth)) * 255).astype(np.uint8), heightFactor, 1 - widthFactor) img_left_bottom = resize_img( np.array(skimage.transform.resize(imgs[2], (mHeight, mWidth)) * 255).astype(np.uint8), 1 - heightFactor, widthFactor) img_right_bottom = resize_img( np.array(skimage.transform.resize(imgs[3], (mHeight, mWidth)) * 255).astype(np.uint8), 1 - heightFactor, 1 - widthFactor) h1 = np.hstack((img_left_top, img_right_top)) h2 = np.hstack((img_left_bottom, img_right_bottom)) return np.vstack((h1, h2))
def do(self): if self.img is not None: if not self.getXmls: if isinstance(self.img, str) or isinstance( self.img, np.ndarray): return resize.resize_img(self.img, self.heightFactor, self.widthFactor) else: res = [] for i in self.img: res.append( resize.resize_img(i, self.heightFactor, self.widthFactor)) return res else: return resize.resizeScript(self.img, self.xml, self.heightFactor, self.widthFactor) else: logger.error('Images are not found!')
def split(folder: str, savaFolder: str, nc: int = 42, multiprocesses=True): global RES txts = glob.glob(folder + os.sep + "*.txt") if not len(txts) > 0: logger.error('Folder is empty, none txt file found!') return trainFile = open(savaFolder + os.sep + 'train.txt', 'w+', encoding='utf-8') trainvalFile = open(savaFolder + os.sep + 'val.txt', 'w+', encoding='utf-8') logger.info('======== start analysing ========') pool = Pool(__CPUS__ - 1) pool_list = [] for t in txts: dic = dict() for k in range(0, nc): dic[k] = 0 resultpool = pool.apply_async(getInfo, (t, dic)) pool_list.append(resultpool) for pr in tqdm(pool_list): res = pr.get() RES.append(res) tmp = getSum(RES) r = getMean(tmp, nc) getTrainValSet(RES, r) global valList for i in list(set(valList)): trainvalFile.write(i.filename + '\n') trainList = list(set(RES).difference(set(valList))) for i in trainList: trainFile.write(i.filename + '\n') trainvalFile.close() trainFile.close()
def do(self): if self.img is not None: if isinstance(self.img, str) or isinstance(self.img, np.ndarray): r = imgFlip(self.img, flag=False) imgH = r.get('h').oriImg imgV = r.get('v').oriImg imgHV = r.get('h_v').oriImg return [imgH, imgV, imgHV] else: res = [] for i in self.img: r = imgFlip(i, flag=False) imgH = r.get('h').oriImg imgV = r.get('v').oriImg imgHV = r.get('h_v').oriImg res.append([imgH, imgV, imgHV]) return res else: logger.error('Images are not found!')
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 generateMaskFile(data, yamlFile): imageHeight = data["imageHeight"] imageWidth = data["imageWidth"] mask = np.zeros((imageHeight, imageWidth)).astype(np.uint8) yamlInfomation = readYamlFile(yamlFile) # print(yamlInfomation) try: shapes = data['shapes'] # print(shapes) for i in shapes: k = i["label"] # print(k) v = readYamlFileVals(yamlInfomation, k) # print(v) polygon = i["points"] if v != 0: # print('lllllllllllllllllll') mask = draw_mask(polygon, mask, int(v)) # print("<==================>".format(np.max(mask))) return mask except Exception as e: logger.error(e)
def getPolygon(xmlPath): in_file = open(xmlPath) tree = ET.parse(in_file) root = tree.getroot() shapes = [] try: for obj in root.iter('object'): flags = {} group_id = 'null' shape_type = 'polygon' # pass dic = dict() label = obj.find('name').text polygon = obj.find('polygon') # print(len(polygon)) if len(polygon) > 2: points = [] for i in range(0, len(polygon)): # print(polygon.find('point{}'.format(i)).text) tmp = polygon.find('point{}'.format(i)).text.split(',') point = [int(tmp[0]), int(tmp[1])] # print(point) points.append(point) del tmp, point dic['flags'] = flags dic['group_id'] = group_id dic['shape_type'] = shape_type dic['points'] = points dic['label'] = label shapes.append(dic) # print(shapes) return shapes except Exception: logger.error(traceback.print_exc())
def x2jConvert_pascal(xmlpath, originImgPath, flag=True): # pass if not os.path.exists(xmlpath) or not os.path.exists(originImgPath): logger.error('file not exist') return base64Code = imgEncode(originImgPath) shapes = getPolygonPascal(xmlpath) (fatherPath, filename_ext) = os.path.split(originImgPath) (filename, _) = os.path.splitext(filename_ext) ob = dict() ob['imageData'] = base64Code ob['flags'] = {} ob['version'] = labelmeVersion ob['imagePath'] = filename_ext img = io.imread(originImgPath) imgShape = img.shape del img ob['imageHeight'] = imgShape[0] ob['imageWidth'] = imgShape[1] ob['shapes'] = shapes if flag: with open(fatherPath + os.sep + filename + '_p.json', 'w', encoding='utf-8') as f: j = json.dumps(ob, sort_keys=True, indent=4) f.write(j) logger.info('save to path {}'.format(fatherPath + os.sep + filename + '_p.json')) return fatherPath + os.sep + filename + '_p.json' else: return json.dumps(ob, sort_keys=True, indent=4)
def mosiacScript_no_reshape(imgs: list, xmls: list, savePath: str, flag=False): heightFactor = random.uniform(0.1, 0.5) widthFactor = random.uniform(0.1, 0.5) img1, img2, img3, img4 = imgs[0], imgs[1], imgs[2], imgs[3] if not type(imgs) is list or not type(xmls) is list: logger.error('Input must be list!') return imgname = getName(xmls) # imgname = 'test1123' folder = savePath mosiacImg, res, _, _ = mosiac_img_no_reshape(imgs, heightFactor, widthFactor) front = res[0] # print(front) # print(heightFactor_,widthFactor_) heightFactor = min(heightFactor, 1 - heightFactor) widthFactor = min(widthFactor, 1 - widthFactor) # print(heightFactor, widthFactor) tree1 = ET.parse(xmls[0]) tree2 = resizeScript(img2, xmls[1], heightFactor=img1.shape[0] / img2.shape[0], widthFactor=img1.shape[1] / img2.shape[1], flag=False) tree3 = resizeScript(img3, xmls[2], heightFactor=img1.shape[0] / img3.shape[0], widthFactor=img1.shape[1] / img3.shape[1], flag=False) tree4 = resizeScript(img4, xmls[3], heightFactor=img1.shape[0] / img4.shape[0], widthFactor=img1.shape[1] / img4.shape[1], flag=False) root1 = tree1.getroot() root2 = tree2.getroot() for box in root2.iter('bndbox'): xmin = float(box.find('xmin').text) ymin = float(box.find('ymin').text) xmax = float(box.find('xmax').text) ymax = float(box.find('ymax').text) box.find('xmin').text = str( int(xmin + widthFactor * mosiacImg.shape[1])) box.find('xmax').text = str( int(xmax + widthFactor * mosiacImg.shape[1])) root3 = tree3.getroot() for box in root3.iter('bndbox'): xmin = float(box.find('xmin').text) ymin = float(box.find('ymin').text) xmax = float(box.find('xmax').text) ymax = float(box.find('ymax').text) box.find('ymin').text = str( int(ymin + heightFactor * mosiacImg.shape[0])) box.find('ymax').text = str( int(ymax + heightFactor * mosiacImg.shape[0])) root4 = tree4.getroot() for box in root4.iter('bndbox'): xmin = float(box.find('xmin').text) ymin = float(box.find('ymin').text) xmax = float(box.find('xmax').text) ymax = float(box.find('ymax').text) box.find('xmin').text = str( int(xmin + widthFactor * mosiacImg.shape[1])) box.find('xmax').text = str( int(xmax + widthFactor * mosiacImg.shape[1])) box.find('ymin').text = str( int(ymin + heightFactor * mosiacImg.shape[0])) box.find('ymax').text = str( int(ymax + heightFactor * mosiacImg.shape[0])) boxes = [] r1, r2, r3, r4 = getBoxes(front, root1, root2, root3, root4, mosiacImg.shape, heightFactor=heightFactor, widthFactor=widthFactor) for box in r1.iter('object'): # print(box) boxes.append(box) for box in r2.iter('object'): # print(box) boxes.append(box) for box in r3.iter('object'): # print(box) boxes.append(box) for box in r4.iter('object'): # print(box) boxes.append(box) # print(len(boxes)) imgshape = mosiacImg.shape objs = [] for o in boxes: obj = dict() name = o.find('name').text difficult = 0 xmlbox = o.find('bndbox') b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) tmp = dict() tmp['xmin'] = str(int(b[0])) tmp['ymin'] = str(int(b[2])) tmp['xmax'] = str(int(b[1])) tmp['ymax'] = str(int(b[3])) # print(tmp) if not (int(tmp['xmin']) == 0 and int(tmp['xmax']) == 0 and int(tmp['ymin']) == 0 and int(tmp['ymax']) == 0): obj['name'] = name obj['difficult'] = difficult obj['bndbox'] = tmp objs.append(obj) del tmp # print(len(objs)) tmpPath = savePath + os.sep + imgname + '.xml' filepath = tmpPath.replace('.xml', '.jpg') filename = imgname + '.jpg' img2xml_multiobj(tmpPath, tmpPath, folder, filename, filepath, imgshape[1], imgshape[0], objs) logger.info('Saved to {}.'.format(tmpPath)) if flag: skimage.io.imsave(filepath, mosiacImg)