visual.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import cv2
  2. import random
  3. import math
  4. import numpy as np
  5. from PIL import Image, ImageDraw, ImageFont
  6. __all__ = ["draw_system", "draw_det"]
  7. def draw_det(dt_boxes, img):
  8. for box in dt_boxes:
  9. box = np.array(box).astype(np.int32).reshape(-1, 2)
  10. cv2.polylines(img, [box], True, color=(255, 255, 0), thickness=2)
  11. return img
  12. def draw_system(
  13. image,
  14. boxes,
  15. txts=None,
  16. scores=None,
  17. drop_score=0.5,
  18. font_path="./doc/fonts/simfang.ttf", ):
  19. h, w = image.height, image.width
  20. img_left = image.copy()
  21. img_right = np.ones((h, w, 3), dtype=np.uint8) * 255
  22. random.seed(0)
  23. draw_left = ImageDraw.Draw(img_left)
  24. if txts is None or len(txts) != len(boxes):
  25. txts = [None] * len(boxes)
  26. for idx, (box, txt) in enumerate(zip(boxes, txts)):
  27. if scores is not None and scores[idx] < drop_score:
  28. continue
  29. color = (random.randint(0, 255), random.randint(0, 255),
  30. random.randint(0, 255))
  31. draw_left.polygon(box, fill=color)
  32. img_right_text = draw_box_txt_fine((w, h), box, txt, font_path)
  33. pts = np.array(box, np.int32).reshape((-1, 1, 2))
  34. cv2.polylines(img_right_text, [pts], True, color, 1)
  35. img_right = cv2.bitwise_and(img_right, img_right_text)
  36. img_left = Image.blend(image, img_left, 0.5)
  37. img_show = Image.new("RGB", (w * 2, h), (255, 255, 255))
  38. img_show.paste(img_left, (0, 0, w, h))
  39. img_show.paste(Image.fromarray(img_right), (w, 0, w * 2, h))
  40. return np.array(img_show)
  41. def draw_box_txt_fine(img_size, box, txt, font_path="./doc/fonts/simfang.ttf"):
  42. box_height = int(
  43. math.sqrt((box[0][0] - box[3][0])**2 + (box[0][1] - box[3][1])**2))
  44. box_width = int(
  45. math.sqrt((box[0][0] - box[1][0])**2 + (box[0][1] - box[1][1])**2))
  46. if box_height > 2 * box_width and box_height > 30:
  47. img_text = Image.new("RGB", (box_height, box_width), (255, 255, 255))
  48. draw_text = ImageDraw.Draw(img_text)
  49. if txt:
  50. font = create_font(txt, (box_height, box_width), font_path)
  51. draw_text.text([0, 0], txt, fill=(0, 0, 0), font=font)
  52. img_text = img_text.transpose(Image.ROTATE_270)
  53. else:
  54. img_text = Image.new("RGB", (box_width, box_height), (255, 255, 255))
  55. draw_text = ImageDraw.Draw(img_text)
  56. if txt:
  57. font = create_font(txt, (box_width, box_height), font_path)
  58. draw_text.text([0, 0], txt, fill=(0, 0, 0), font=font)
  59. pts1 = np.float32(
  60. [[0, 0], [box_width, 0], [box_width, box_height], [0, box_height]])
  61. pts2 = np.array(box, dtype=np.float32)
  62. M = cv2.getPerspectiveTransform(pts1, pts2)
  63. img_text = np.array(img_text, dtype=np.uint8)
  64. img_right_text = cv2.warpPerspective(
  65. img_text,
  66. M,
  67. img_size,
  68. flags=cv2.INTER_NEAREST,
  69. borderMode=cv2.BORDER_CONSTANT,
  70. borderValue=(255, 255, 255), )
  71. return img_right_text
  72. def create_font(txt, sz, font_path="./doc/fonts/simfang.ttf"):
  73. font_size = int(sz[1] * 0.99)
  74. font = ImageFont.truetype(font_path, font_size, encoding="utf-8")
  75. length = font.getlength(txt)
  76. if length > sz[0]:
  77. font_size = int(font_size * sz[0] / length)
  78. font = ImageFont.truetype(font_path, font_size, encoding="utf-8")
  79. return font
  80. def str_count(s):
  81. """
  82. Count the number of Chinese characters,
  83. a single English character and a single number
  84. equal to half the length of Chinese characters.
  85. args:
  86. s(string): the input of string
  87. return(int):
  88. the number of Chinese characters
  89. """
  90. import string
  91. count_zh = count_pu = 0
  92. s_len = len(s)
  93. en_dg_count = 0
  94. for c in s:
  95. if c in string.ascii_letters or c.isdigit() or c.isspace():
  96. en_dg_count += 1
  97. elif c.isalpha():
  98. count_zh += 1
  99. else:
  100. count_pu += 1
  101. return s_len - math.ceil(en_dg_count / 2)