utils.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. # Copyright (c) Alibaba, Inc. and its affiliates.
  2. import os
  3. import random
  4. import cv2
  5. import numpy as np
  6. import tensorflow as tf
  7. def resize_size(image, size=720):
  8. h, w, c = np.shape(image)
  9. if min(h, w) > size:
  10. if h > w:
  11. h, w = int(size * h / w), size
  12. else:
  13. h, w = size, int(size * w / h)
  14. image = cv2.resize(image, (w, h), interpolation=cv2.INTER_AREA)
  15. return image
  16. def padTo16x(image):
  17. h, w, c = np.shape(image)
  18. if h % 16 == 0 and w % 16 == 0:
  19. return image, h, w
  20. nh, nw = (h // 16 + 1) * 16, (w // 16 + 1) * 16
  21. img_new = np.ones((nh, nw, 3), np.uint8) * 255
  22. img_new[:h, :w, :] = image
  23. return img_new, h, w
  24. def get_f5p(landmarks, np_img):
  25. eye_left = find_pupil(landmarks[36:41], np_img)
  26. eye_right = find_pupil(landmarks[42:47], np_img)
  27. if eye_left is None or eye_right is None:
  28. print('cannot find 5 points with find_puil, used mean instead.!')
  29. eye_left = landmarks[36:41].mean(axis=0)
  30. eye_right = landmarks[42:47].mean(axis=0)
  31. nose = landmarks[30]
  32. mouth_left = landmarks[48]
  33. mouth_right = landmarks[54]
  34. f5p = [[eye_left[0], eye_left[1]], [eye_right[0], eye_right[1]],
  35. [nose[0], nose[1]], [mouth_left[0], mouth_left[1]],
  36. [mouth_right[0], mouth_right[1]]]
  37. return f5p
  38. def find_pupil(landmarks, np_img):
  39. h, w, _ = np_img.shape
  40. xmax = int(landmarks[:, 0].max())
  41. xmin = int(landmarks[:, 0].min())
  42. ymax = int(landmarks[:, 1].max())
  43. ymin = int(landmarks[:, 1].min())
  44. if ymin >= ymax or xmin >= xmax or ymin < 0 or xmin < 0 or ymax > h or xmax > w:
  45. return None
  46. eye_img_bgr = np_img[ymin:ymax, xmin:xmax, :]
  47. eye_img = cv2.cvtColor(eye_img_bgr, cv2.COLOR_BGR2GRAY)
  48. eye_img = cv2.equalizeHist(eye_img)
  49. n_marks = landmarks - np.array([xmin, ymin]).reshape([1, 2])
  50. eye_mask = cv2.fillConvexPoly(
  51. np.zeros_like(eye_img), n_marks.astype(np.int32), 1)
  52. ret, thresh = cv2.threshold(eye_img, 100, 255,
  53. cv2.THRESH_BINARY | cv2.THRESH_OTSU)
  54. thresh = (1 - thresh / 255.) * eye_mask
  55. cnt = 0
  56. xm = []
  57. ym = []
  58. for i in range(thresh.shape[0]):
  59. for j in range(thresh.shape[1]):
  60. if thresh[i, j] > 0.5:
  61. xm.append(j)
  62. ym.append(i)
  63. cnt += 1
  64. if cnt != 0:
  65. xm.sort()
  66. ym.sort()
  67. xm = xm[cnt // 2]
  68. ym = ym[cnt // 2]
  69. else:
  70. xm = thresh.shape[1] / 2
  71. ym = thresh.shape[0] / 2
  72. return xm + xmin, ym + ymin
  73. def next_batch(filename_list, batch_size, fineSize=256):
  74. idx = np.arange(0, len(filename_list))
  75. np.random.shuffle(idx)
  76. idx = idx[:batch_size]
  77. batch_data = []
  78. for i in range(batch_size):
  79. image = cv2.imread(filename_list[idx[i]])
  80. h, w, c = image.shape
  81. rw = random.randint(0, w - fineSize)
  82. rh = random.randint(0, h - fineSize)
  83. image = image[rh:rh + fineSize, rw:rw + fineSize, :]
  84. image = image.astype(np.float32) / 127.5 - 1
  85. batch_data.append(image)
  86. return np.asarray(batch_data)
  87. def read_image(image_path, IMAGE_SIZE=256):
  88. image = tf.io.read_file(image_path)
  89. image = tf.image.decode_image(image, channels=3)
  90. image = tf.image.convert_image_dtype(image, tf.float32)
  91. image.set_shape([None, None, 3])
  92. image = tf.image.resize(images=image, size=[IMAGE_SIZE, IMAGE_SIZE])
  93. image = image[..., ::-1]
  94. # image = image / 127.5 - 1
  95. image = (image - 0.5) * 2
  96. return image
  97. def load_data(photo_list):
  98. photo = read_image(photo_list)
  99. return photo
  100. def tf_data_loader(image_list, batch_size):
  101. dataset = tf.data.Dataset.from_tensor_slices((image_list))
  102. dataset = dataset.shuffle(len(image_list))
  103. dataset = dataset.map(load_data, num_parallel_calls=4)
  104. dataset = dataset.batch(batch_size)
  105. dataset = dataset.prefetch(1)
  106. return dataset
  107. def write_batch_image(image, save_dir, name, n):
  108. if not os.path.exists(save_dir):
  109. os.makedirs(save_dir)
  110. fused_dir = os.path.join(save_dir, name)
  111. fused_image = [0] * n
  112. for i in range(n):
  113. fused_image[i] = []
  114. for j in range(n):
  115. k = i * n + j
  116. image[k] = (image[k] + 1) * 127.5
  117. image[k] = np.clip(image[k], 0, 255)
  118. fused_image[i].append(image[k])
  119. fused_image[i] = np.hstack(fused_image[i])
  120. fused_image = np.vstack(fused_image)
  121. cv2.imwrite(fused_dir, fused_image.astype(np.uint8))
  122. def grid_batch_image(image, n):
  123. fused_image = [0] * n
  124. for i in range(n):
  125. fused_image[i] = []
  126. for j in range(n):
  127. k = i * n + j
  128. image[k] = (image[k] + 1) * 127.5
  129. image[k] = np.clip(image[k], 0, 255)
  130. fused_image[i].append(image[k])
  131. fused_image[i] = np.hstack(fused_image[i])
  132. fused_image = np.vstack(fused_image)
  133. return fused_image
  134. def all_file(file_dir):
  135. L = []
  136. for root, dirs, files in os.walk(file_dir):
  137. for file in files:
  138. extend = os.path.splitext(file)[1]
  139. if extend == '.png' or extend == '.jpg' or extend == '.jpeg' or extend == '.JPG':
  140. L.append(os.path.join(root, file))
  141. return L