import click

from pathlib import Path
import datetime
from moviepy.editor import *
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import numpy as np
import xmltodict

def make_clips(filelist,timelist,AOI=None):
    print('loopstart')
    clips=[]
    for file, time in zip(filelist, timelist):
        print(f'processing image {file.name}')

        if AOI is None:
            img=Image.open(file)
        else:

            if ((int(AOI['xmax'])-int(AOI['xmin'])) % 2) == 1:
                print('make AOI even')
                AOI['xmax']=int(AOI['xmax'])-1
                
            if ((int(AOI['ymax'])-int(AOI['ymin'])) % 2) == 1:
                print('make AOI even')
                AOI['ymax']=int(AOI['ymax'])-1

            img=Image.open(file).crop((int(AOI['xmin']),int(AOI['ymin']),int(AOI['xmax']),int(AOI['ymax'])))

        font = ImageFont.truetype("arial.ttf", int(max(img.size)/20))

        ImageDraw.Draw(img).text((0,0), str(time).split('.')[0],font=font)
        clip =ImageClip(np.array(img)).set_duration(0.1)
        clips.append(clip)
    return clips


@click.command()
@click.option('--exp_folder', default='.', help='Path to experiment folder with images. Exp_folder will be also used to name the timelapse video')
@click.option('--xml_mask', default=None, help='Path to xml file with 1 or multiple masks generated by labelimg ')

def main(exp_folder, xml_mask=None):
    '''Read images in exp_folder, finds date created, 
    stamps it on the image and generate mp4 video 
    named as exp_folder in current folder
    
    Added parameter xml_mask'''
    
    exp_folder=Path(exp_folder)
    
    print(f'Processing images in folder: {exp_folder.resolve()}')
    
    p = Path(exp_folder).glob('**/*')
          
    filelist = [item for item in p if item.is_file() and item.suffix in ['.jpg','.bmp','.BMP','.JPG','.png','.PNG']]
    timelist = [datetime.datetime.fromtimestamp(file.stat().st_mtime) for file in filelist]
    timelist = list(map(lambda x: x-timelist[0],timelist))

    if xml_mask is None:
        clips=make_clips(filelist,timelist)
        concat_clip = concatenate_videoclips(clips, method='compose')
        concat_clip.write_videofile(f"{exp_folder.name}.mp4", fps=24)

    else:
        with open(xml_mask, 'r') as file:
            AOI_from_XML=xmltodict.parse(file.read())
        AOI_dict={}
        for AOI in AOI_from_XML['annotation']['object']:
            try:
              AOI_dict[AOI['name']]=AOI['bndbox']
            except:
              AOI_dict['name']=AOI_from_XML['annotation']['object']['bndbox']
        
        for AOI_name, AOI in AOI_dict.items():
            clips=make_clips(filelist,timelist,AOI=AOI)
            concat_clip = concatenate_videoclips(clips, method='compose')
            concat_clip.write_videofile(f"{AOI_name}_{exp_folder.name}.mp4", fps=24)

if __name__ == '__main__':
    sys.exit(main())

import click

from pathlib import Path
import datetime
from moviepy.editor import *
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import numpy as np
import xmltodict

def make_clips(filelist,timelist,AOI=None):
    print('loopstart')
    clips=[]
    for file, time in zip(filelist, timelist):
        print(f'processing image {file.name}')

        if AOI is None:
            img=Image.open(file)
        else:

            if ((int(AOI['xmax'])-int(AOI['xmin'])) % 2) == 1:
                print('make AOI even')
                AOI['xmax']=int(AOI['xmax'])-1
                
            if ((int(AOI['ymax'])-int(AOI['ymin'])) % 2) == 1:
                print('make AOI even')
                AOI['ymax']=int(AOI['ymax'])-1

            img=Image.open(file).crop((int(AOI['xmin']),int(AOI['ymin']),int(AOI['xmax']),int(AOI['ymax'])))

        font = ImageFont.truetype("arial.ttf", int(max(img.size)/20))

        ImageDraw.Draw(img).text((0,0), str(time).split('.')[0],font=font)
        clip =ImageClip(np.array(img)).set_duration(0.1)
        clips.append(clip)
    return clips


@click.command()
@click.option('--exp_folder', default='.', help='Path to experiment folder with images. Exp_folder will be also used to name the timelapse video')
@click.option('--xml_mask', default=None, help='Path to xml file with 1 or multiple masks generated by labelimg ')

def main(exp_folder, xml_mask=None):
    '''Read images in exp_folder, finds date created, 
    stamps it on the image and generate mp4 video 
    named as exp_folder in current folder
    
    Added parameter xml_mask'''
    
    exp_folder=Path(exp_folder)
    
    print(f'Processing images in folder: {exp_folder.resolve()}')
    
    p = Path(exp_folder).glob('**/*')
          
    filelist = [item for item in p if item.is_file() and item.suffix in ['.jpg','.bmp','.BMP','.JPG','.png','.PNG']]
    timelist = [datetime.datetime.fromtimestamp(file.stat().st_mtime) for file in filelist]
    timelist = list(map(lambda x: x-timelist[0],timelist))

    if xml_mask is None:
        clips=make_clips(filelist,timelist)
        concat_clip = concatenate_videoclips(clips, method='compose')
        concat_clip.write_videofile(f"{exp_folder.name}.mp4", fps=24)

    else:
        with open(xml_mask, 'r') as file:
            AOI_from_XML=xmltodict.parse(file.read())
        AOI_dict={}
        for AOI in AOI_from_XML['annotation']['object']:
            try:
              AOI_dict[AOI['name']]=AOI['bndbox']
            except:
              AOI_dict['name']=AOI_from_XML['annotation']['object']['bndbox']
        
        for AOI_name, AOI in AOI_dict.items():
            clips=make_clips(filelist,timelist,AOI=AOI)
            concat_clip = concatenate_videoclips(clips, method='compose')
            concat_clip.write_videofile(f"{AOI_name}_{exp_folder.name}.mp4", fps=24)

if __name__ == '__main__':
    sys.exit(main())

Read images in exp_folder, finds date created,      stamps it on the image and generate mp4 video      named as exp_folder in current folder          Added parameter xml_mask