예제 #1
0
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
예제 #2
0
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)
예제 #3
0
    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))
예제 #5
0
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]\}'
        )
예제 #6
0
파일: x2m.py 프로젝트: wwdok/mask2json
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
예제 #7
0
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()
예제 #8
0
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))
예제 #9
0
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)
예제 #10
0
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
예제 #11
0
 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!')
예제 #12
0
 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!')
예제 #13
0
 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!')
예제 #14
0
 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!')
예제 #15
0
 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!')
예제 #16
0
파일: genrate.py 프로젝트: wwdok/mask2json
    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()
예제 #17
0
 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!')
예제 #18
0
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
예제 #19
0
    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!')
예제 #20
0
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())
예제 #21
0
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)
예제 #22
0
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))
예제 #23
0
 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!')
예제 #24
0
파일: yololike.py 프로젝트: wwdok/mask2json
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()
예제 #25
0
    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!')
예제 #26
0
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))
예제 #27
0
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)
예제 #28
0
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())
예제 #29
0
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)
예제 #30
0
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)