text: # Copyright (c) OpenMMLab. All rights reserved.
  import argparse
  import os
  import os.path as osp
  
  import matplotlib.patches as mpatches
  import matplotlib.pyplot as plt
  import mmcv
  import numpy as np
  
  try:
      import imageio
  except ImportError:
      imageio = None
  
  
  def parse_args():
      parser = argparse.ArgumentParser(description='Create GIF for demo')
      parser.add_argument(
          'image_dir',
          help='directory where result '
          'images save path generated by ‘analyze_results.py’')
      parser.add_argument(
          '--out',
          type=str,
          default='result.gif',
          help='gif path where will be saved')
      args = parser.parse_args()
      return args
  
  
  def _generate_batch_data(sampler, batch_size):
      batch = []
      for idx in sampler:
          batch.append(idx)
          if len(batch) == batch_size:
              yield batch
              batch = []
      if len(batch) > 0:
          yield batch
  
  
  def create_gif(frames, gif_name, duration=2):
      """Create gif through imageio.
  
      Args:
          frames (list[ndarray]): Image frames
          gif_name (str): Saved gif name
          duration (int): Display interval (s),
              Default: 2
      """
      if imageio is None:
          raise RuntimeError('imageio is not installed,'
                             'Please use “pip install imageio” to install')
      imageio.mimsave(gif_name, frames, 'GIF', duration=duration)
  
  
  def create_frame_by_matplotlib(image_dir,
                                 nrows=1,
                                 fig_size=(300, 300),
                                 font_size=15):
      """Create gif frame image through matplotlib.
  
      Args:
          image_dir (str): Root directory of result images
          nrows (int): Number of rows displayed, Default: 1
          fig_size (tuple): Figure size of the pyplot figure.
             Default: (300, 300)
          font_size (int): Font size of texts. Default: 15
  
      Returns:
          list[ndarray]: image frames
      """
  
      result_dir_names = os.listdir(image_dir)
      assert len(result_dir_names) == 2
      # Longer length has higher priority
      result_dir_names.reverse()
  
      images_list = []
      for dir_names in result_dir_names:
          images_list.append(mmcv.scandir(osp.join(image_dir, dir_names)))
  
      frames = []
      for paths in _generate_batch_data(zip(*images_list), nrows):
  
          fig, axes = plt.subplots(nrows=nrows, ncols=2)
          fig.suptitle('Good/bad case selected according '
                       'to the COCO mAP of the single image')
  
          det_patch = mpatches.Patch(color='salmon', label='prediction')
          gt_patch = mpatches.Patch(color='royalblue', label='ground truth')
          # bbox_to_anchor may need to be finetuned
          plt.legend(
              handles=[det_patch, gt_patch],
              bbox_to_anchor=(1, -0.18),
              loc='lower right',
              borderaxespad=0.)
  
          if nrows == 1:
              axes = [axes]
  
          dpi = fig.get_dpi()
          # set fig size and margin
          fig.set_size_inches(
              (fig_size[0] * 2 + fig_size[0] // 20) / dpi,
              (fig_size[1] * nrows + fig_size[1] // 3) / dpi,
          )
  
          fig.tight_layout()
          # set subplot margin
          plt.subplots_adjust(
              hspace=.05,
              wspace=0.05,
              left=0.02,
              right=0.98,
              bottom=0.02,
              top=0.98)
  
          for i, (path_tuple, ax_tuple) in enumerate(zip(paths, axes)):
              image_path_left = osp.join(
                  osp.join(image_dir, result_dir_names[0], path_tuple[0]))
              image_path_right = osp.join(
                  osp.join(image_dir, result_dir_names[1], path_tuple[1]))
              image_left = mmcv.imread(image_path_left)
              image_left = mmcv.rgb2bgr(image_left)
              image_right = mmcv.imread(image_path_right)
              image_right = mmcv.rgb2bgr(image_right)
  
              if i == 0:
                  ax_tuple[0].set_title(
                      result_dir_names[0], fontdict={'size': font_size})
                  ax_tuple[1].set_title(
                      result_dir_names[1], fontdict={'size': font_size})
              ax_tuple[0].imshow(
                  image_left, extent=(0, *fig_size, 0), interpolation='bilinear')
              ax_tuple[0].axis('off')
              ax_tuple[1].imshow(
                  image_right,
                  extent=(0, *fig_size, 0),
                  interpolation='bilinear')
              ax_tuple[1].axis('off')
  
          canvas = fig.canvas
          s, (width, height) = canvas.print_to_buffer()
          buffer = np.frombuffer(s, dtype='uint8')
          img_rgba = buffer.reshape(height, width, 4)
          rgb, alpha = np.split(img_rgba, [3], axis=2)
          img = rgb.astype('uint8')
  
          frames.append(img)
  
      return frames
  
  
  def main():
      args = parse_args()
      frames = create_frame_by_matplotlib(args.image_dir)
      create_gif(frames, args.out)
  
  
  if __name__ == '__main__':
      main()
  