def get_image_dims(mega_db_seqs, dataset_name, datasets_table, n_cores):

    images_to_get_dims_for = []

    for seq in tqdm(mega_db_seqs):
        assert 'seq_id' in seq and 'images' in seq
        for i in seq['images']:
            assert 'file' in i

        for im in seq['images']:
            if 'bbox' in im and len(im['bbox']) > 1:
                if 'id' not in im:
                    im['id'] = str(uuid.uuid1())
                images_to_get_dims_for.append(im)

    print('Getting the dimensions for {} images'.format(
        len(images_to_get_dims_for)))

    blob_service = MegadbUtils.get_blob_service(datasets_table, dataset_name)
    path_prefix = datasets_table[dataset_name]['path_prefix']
    container_name = datasets_table[dataset_name]['container']

    if n_cores:
        print('Using threads to download images')
        pool = workerpool(n_cores)
        updated_im_objects = pool.map(
            partial(_get_image_dims, blob_service, path_prefix,
                    container_name), images_to_get_dims_for)
        print('pool.map has returned')
    else:
        print('Downloading images sequentially')
        updated_im_objects = []
        for image_obj in tqdm(images_to_get_dims_for):
            updated_im_objects.append(
                get_image_dims(blob_service, path_prefix, container_name,
                               image_obj))
    print('Successfully updated {} images.'.format(len(updated_im_objects)))
    updated_im_objects = {i['id']: i for i in updated_im_objects}

    # update the sequences
    print('Updating the sequence objects...')
    for seq in tqdm(mega_db_seqs):
        updated_images = []
        for im in seq['images']:
            if 'bbox' in im and im['id'] in updated_im_objects:
                updated_images.append(updated_im_objects[im['id']])
            else:
                updated_images.append(im)
        seq['images'] = updated_images

    return mega_db_seqs
def visualize_sequences(datasets_table, sequences, args):
    num_images = 0

    images_html = []
    rendering_info = []

    for seq in sequences:
        if 'images' not in seq:
            continue

        # dataset and seq_id are required fields
        dataset_name = seq['dataset']
        seq_id = seq['seq_id']

        # sort the images in the sequence

        images_in_seq = sorted(seq['images'], key=lambda x: x['frame_num']) if len(seq['images']) > 1 else seq['images']

        for im in images_in_seq:
            if args.trim_to_images_bboxes_labeled and 'bbox' not in im:
                continue

            num_images += 1

            blob_path = MegadbUtils.get_full_path(datasets_table, dataset_name, im['file'])
            frame_num = im.get('frame_num', -1)
            im_class = im.get('class', None)
            if im_class is None:  # if no class label on the image, show the class label on the sequence
                im_class = seq.get('class', [])

            rendering = {}
            rendering['blob_service'] = MegadbUtils.get_blob_service(datasets_table, dataset_name)
            rendering['container_name'] = datasets_table[dataset_name]['container']
            rendering['blob_path'] = blob_path
            rendering['bbox'] = im.get('bbox', [])

            annotated_img_name = 'anno_' + blob_path.replace('/', args.pathsep_replacement).replace('\\', args.pathsep_replacement)
            rendering['annotated_img_name'] = annotated_img_name

            rendering_info.append(rendering)

            images_html.append({
                'filename': 'rendered_images/{}'.format(annotated_img_name),
                'title': 'Seq ID: {}. Frame number: {}<br/> Image file: {}<br/> number of boxes: {}, image class labels: {}'.format(seq_id, frame_num, blob_path, len(rendering['bbox']), im_class),
                'textStyle': 'font-family:verdana,arial,calibri;font-size:80%;text-align:left;margin-top:20;margin-bottom:5'
            })

        if num_images >= args.num_to_visualize:
            print('num_images visualized is {}'.format(num_images))
            break

    # pool = ThreadPool()
    render_image_info_partial = partial(render_image_info, args=args)
    # print('len of rendering_info', len(rendering_info))
    # tqdm(pool.imap_unordered(render_image_info_partial, rendering_info), total=len(rendering_info))

    for rendering in tqdm(rendering_info):
        render_image_info_partial(rendering)

    print('Making HTML...')

    html_path = os.path.join(args.output_dir, 'index.html')
    # options = write_html_image_list()
    # options['headerHtml']
    write_html_image_list(
        filename=html_path,
        images=images_html
    )