utils.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import datetime
  2. import os
  3. import cv2
  4. import numpy as np
  5. from PIL import Image, ImageDraw
  6. def save_images(img_list, folder):
  7. if not os.path.exists(folder):
  8. os.makedirs(folder)
  9. now = datetime.datetime.now()
  10. date_str = now.strftime("%Y-%m-%d")
  11. folder_path = os.path.join(folder, date_str)
  12. if not os.path.exists(folder_path):
  13. os.makedirs(folder_path)
  14. time_str = now.strftime("%H_%M_%S")
  15. for idx, img in enumerate(img_list):
  16. image_number = idx + 1
  17. filename = f"{time_str}_{image_number}.jpg"
  18. save_path = os.path.join(folder_path, filename)
  19. cv2.imwrite(save_path, img[..., ::-1])
  20. def check_channels(image):
  21. channels = image.shape[2] if len(image.shape) == 3 else 1
  22. if channels == 1:
  23. image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
  24. elif channels > 3:
  25. image = image[:, :, :3]
  26. return image
  27. def resize_image(img, max_length=768):
  28. height, width = img.shape[:2]
  29. max_dimension = max(height, width)
  30. if max_dimension > max_length:
  31. scale_factor = max_length / max_dimension
  32. new_width = int(round(width * scale_factor))
  33. new_height = int(round(height * scale_factor))
  34. new_size = (new_width, new_height)
  35. img = cv2.resize(img, new_size)
  36. height, width = img.shape[:2]
  37. img = cv2.resize(img, (width - (width % 64), height - (height % 64)))
  38. return img
  39. def insert_spaces(string, nSpace):
  40. if nSpace == 0:
  41. return string
  42. new_string = ""
  43. for char in string:
  44. new_string += char + " " * nSpace
  45. return new_string[:-nSpace]
  46. def draw_glyph(font, text):
  47. g_size = 50
  48. W, H = (512, 80)
  49. new_font = font.font_variant(size=g_size)
  50. img = Image.new(mode="1", size=(W, H), color=0)
  51. draw = ImageDraw.Draw(img)
  52. left, top, right, bottom = new_font.getbbox(text)
  53. text_width = max(right - left, 5)
  54. text_height = max(bottom - top, 5)
  55. ratio = min(W * 0.9 / text_width, H * 0.9 / text_height)
  56. new_font = font.font_variant(size=int(g_size * ratio))
  57. text_width, text_height = new_font.getsize(text)
  58. offset_x, offset_y = new_font.getoffset(text)
  59. x = (img.width - text_width) // 2
  60. y = (img.height - text_height) // 2 - offset_y // 2
  61. draw.text((x, y), text, font=new_font, fill="white")
  62. img = np.expand_dims(np.array(img), axis=2).astype(np.float64)
  63. return img
  64. def draw_glyph2(
  65. font, text, polygon, vertAng=10, scale=1, width=512, height=512, add_space=True
  66. ):
  67. enlarge_polygon = polygon * scale
  68. rect = cv2.minAreaRect(enlarge_polygon)
  69. box = cv2.boxPoints(rect)
  70. box = np.int0(box)
  71. w, h = rect[1]
  72. angle = rect[2]
  73. if angle < -45:
  74. angle += 90
  75. angle = -angle
  76. if w < h:
  77. angle += 90
  78. vert = False
  79. if abs(angle) % 90 < vertAng or abs(90 - abs(angle) % 90) % 90 < vertAng:
  80. _w = max(box[:, 0]) - min(box[:, 0])
  81. _h = max(box[:, 1]) - min(box[:, 1])
  82. if _h >= _w:
  83. vert = True
  84. angle = 0
  85. img = np.zeros((height * scale, width * scale, 3), np.uint8)
  86. img = Image.fromarray(img)
  87. # infer font size
  88. image4ratio = Image.new("RGB", img.size, "white")
  89. draw = ImageDraw.Draw(image4ratio)
  90. _, _, _tw, _th = draw.textbbox(xy=(0, 0), text=text, font=font)
  91. text_w = min(w, h) * (_tw / _th)
  92. if text_w <= max(w, h):
  93. # add space
  94. if len(text) > 1 and not vert and add_space:
  95. for i in range(1, 100):
  96. text_space = insert_spaces(text, i)
  97. _, _, _tw2, _th2 = draw.textbbox(xy=(0, 0), text=text_space, font=font)
  98. if min(w, h) * (_tw2 / _th2) > max(w, h):
  99. break
  100. text = insert_spaces(text, i - 1)
  101. font_size = min(w, h) * 0.80
  102. else:
  103. shrink = 0.75 if vert else 0.85
  104. font_size = min(w, h) / (text_w / max(w, h)) * shrink
  105. new_font = font.font_variant(size=int(font_size))
  106. left, top, right, bottom = new_font.getbbox(text)
  107. text_width = right - left
  108. text_height = bottom - top
  109. layer = Image.new("RGBA", img.size, (0, 0, 0, 0))
  110. draw = ImageDraw.Draw(layer)
  111. if not vert:
  112. draw.text(
  113. (rect[0][0] - text_width // 2, rect[0][1] - text_height // 2 - top),
  114. text,
  115. font=new_font,
  116. fill=(255, 255, 255, 255),
  117. )
  118. else:
  119. x_s = min(box[:, 0]) + _w // 2 - text_height // 2
  120. y_s = min(box[:, 1])
  121. for c in text:
  122. draw.text((x_s, y_s), c, font=new_font, fill=(255, 255, 255, 255))
  123. _, _t, _, _b = new_font.getbbox(c)
  124. y_s += _b
  125. rotated_layer = layer.rotate(angle, expand=1, center=(rect[0][0], rect[0][1]))
  126. x_offset = int((img.width - rotated_layer.width) / 2)
  127. y_offset = int((img.height - rotated_layer.height) / 2)
  128. img.paste(rotated_layer, (x_offset, y_offset), rotated_layer)
  129. img = np.expand_dims(np.array(img.convert("1")), axis=2).astype(np.float64)
  130. return img