generate_imagematte_with_background_image.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. """
  2. python generate_imagematte_with_background_image.py \
  3. --imagematte-dir ../matting-data/Distinctions/test \
  4. --background-dir ../matting-data/Backgrounds/valid \
  5. --resolution 512 \
  6. --out-dir ../matting-data/evaluation/distinction_static_sd/ \
  7. --random-seed 10
  8. Seed:
  9. 10 - distinction-static
  10. 11 - distinction-motion
  11. 12 - adobe-static
  12. 13 - adobe-motion
  13. """
  14. import argparse
  15. import os
  16. import pims
  17. import numpy as np
  18. import random
  19. from PIL import Image
  20. from tqdm import tqdm
  21. from tqdm.contrib.concurrent import process_map
  22. from torchvision import transforms
  23. from torchvision.transforms import functional as F
  24. parser = argparse.ArgumentParser()
  25. parser.add_argument('--imagematte-dir', type=str, required=True)
  26. parser.add_argument('--background-dir', type=str, required=True)
  27. parser.add_argument('--num-samples', type=int, default=20)
  28. parser.add_argument('--num-frames', type=int, default=100)
  29. parser.add_argument('--resolution', type=int, required=True)
  30. parser.add_argument('--out-dir', type=str, required=True)
  31. parser.add_argument('--random-seed', type=int)
  32. parser.add_argument('--extension', type=str, default='.png')
  33. args = parser.parse_args()
  34. random.seed(args.random_seed)
  35. imagematte_filenames = os.listdir(os.path.join(args.imagematte_dir, 'fgr'))
  36. background_filenames = os.listdir(args.background_dir)
  37. random.shuffle(imagematte_filenames)
  38. random.shuffle(background_filenames)
  39. def lerp(a, b, percentage):
  40. return a * (1 - percentage) + b * percentage
  41. def motion_affine(*imgs):
  42. config = dict(degrees=(-10, 10), translate=(0.1, 0.1),
  43. scale_ranges=(0.9, 1.1), shears=(-5, 5), img_size=imgs[0][0].size)
  44. angleA, (transXA, transYA), scaleA, (shearXA, shearYA) = transforms.RandomAffine.get_params(**config)
  45. angleB, (transXB, transYB), scaleB, (shearXB, shearYB) = transforms.RandomAffine.get_params(**config)
  46. T = len(imgs[0])
  47. variation_over_time = random.random()
  48. for t in range(T):
  49. percentage = (t / (T - 1)) * variation_over_time
  50. angle = lerp(angleA, angleB, percentage)
  51. transX = lerp(transXA, transXB, percentage)
  52. transY = lerp(transYA, transYB, percentage)
  53. scale = lerp(scaleA, scaleB, percentage)
  54. shearX = lerp(shearXA, shearXB, percentage)
  55. shearY = lerp(shearYA, shearYB, percentage)
  56. for img in imgs:
  57. img[t] = F.affine(img[t], angle, (transX, transY), scale, (shearX, shearY), F.InterpolationMode.BILINEAR)
  58. return imgs
  59. def process(i):
  60. imagematte_filename = imagematte_filenames[i % len(imagematte_filenames)]
  61. background_filename = background_filenames[i % len(background_filenames)]
  62. out_path = os.path.join(args.out_dir, str(i).zfill(4))
  63. os.makedirs(os.path.join(out_path, 'fgr'), exist_ok=True)
  64. os.makedirs(os.path.join(out_path, 'pha'), exist_ok=True)
  65. os.makedirs(os.path.join(out_path, 'com'), exist_ok=True)
  66. os.makedirs(os.path.join(out_path, 'bgr'), exist_ok=True)
  67. with Image.open(os.path.join(args.background_dir, background_filename)) as bgr:
  68. bgr = bgr.convert('RGB')
  69. w, h = bgr.size
  70. scale = args.resolution / min(h, w)
  71. w, h = int(w * scale), int(h * scale)
  72. bgr = bgr.resize((w, h))
  73. bgr = F.center_crop(bgr, (args.resolution, args.resolution))
  74. with Image.open(os.path.join(args.imagematte_dir, 'fgr', imagematte_filename)) as fgr, \
  75. Image.open(os.path.join(args.imagematte_dir, 'pha', imagematte_filename)) as pha:
  76. fgr = fgr.convert('RGB')
  77. pha = pha.convert('L')
  78. fgrs = [fgr] * args.num_frames
  79. phas = [pha] * args.num_frames
  80. fgrs, phas = motion_affine(fgrs, phas)
  81. for t in tqdm(range(args.num_frames), desc=str(i).zfill(4)):
  82. fgr = fgrs[t]
  83. pha = phas[t]
  84. w, h = fgr.size
  85. scale = args.resolution / max(h, w)
  86. w, h = int(w * scale), int(h * scale)
  87. fgr = fgr.resize((w, h))
  88. pha = pha.resize((w, h))
  89. if h < args.resolution:
  90. pt = (args.resolution - h) // 2
  91. pb = args.resolution - h - pt
  92. else:
  93. pt = 0
  94. pb = 0
  95. if w < args.resolution:
  96. pl = (args.resolution - w) // 2
  97. pr = args.resolution - w - pl
  98. else:
  99. pl = 0
  100. pr = 0
  101. fgr = F.pad(fgr, [pl, pt, pr, pb])
  102. pha = F.pad(pha, [pl, pt, pr, pb])
  103. if i // len(imagematte_filenames) % 2 == 1:
  104. fgr = fgr.transpose(Image.FLIP_LEFT_RIGHT)
  105. pha = pha.transpose(Image.FLIP_LEFT_RIGHT)
  106. fgr.save(os.path.join(out_path, 'fgr', str(t).zfill(4) + args.extension))
  107. pha.save(os.path.join(out_path, 'pha', str(t).zfill(4) + args.extension))
  108. if t == 0:
  109. bgr.save(os.path.join(out_path, 'bgr', str(t).zfill(4) + args.extension))
  110. else:
  111. os.symlink(str(0).zfill(4) + args.extension, os.path.join(out_path, 'bgr', str(t).zfill(4) + args.extension))
  112. pha = np.asarray(pha).astype(float)[:, :, None] / 255
  113. com = Image.fromarray(np.uint8(np.asarray(fgr) * pha + np.asarray(bgr) * (1 - pha)))
  114. com.save(os.path.join(out_path, 'com', str(t).zfill(4) + args.extension))
  115. if __name__ == '__main__':
  116. r = process_map(process, range(args.num_samples), max_workers=32)