You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #
  2. # Copyright 2025 The InfiniFlow Authors. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. import logging
  17. import os
  18. import PIL
  19. from PIL import ImageDraw
  20. def save_results(image_list, results, labels, output_dir='output/', threshold=0.5):
  21. if not os.path.exists(output_dir):
  22. os.makedirs(output_dir)
  23. for idx, im in enumerate(image_list):
  24. im = draw_box(im, results[idx], labels, threshold=threshold)
  25. out_path = os.path.join(output_dir, f"{idx}.jpg")
  26. im.save(out_path, quality=95)
  27. logging.debug("save result to: " + out_path)
  28. def draw_box(im, result, lables, threshold=0.5):
  29. draw_thickness = min(im.size) // 320
  30. draw = ImageDraw.Draw(im)
  31. color_list = get_color_map_list(len(lables))
  32. clsid2color = {n.lower():color_list[i] for i,n in enumerate(lables)}
  33. result = [r for r in result if r["score"] >= threshold]
  34. for dt in result:
  35. color = tuple(clsid2color[dt["type"]])
  36. xmin, ymin, xmax, ymax = dt["bbox"]
  37. draw.line(
  38. [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin),
  39. (xmin, ymin)],
  40. width=draw_thickness,
  41. fill=color)
  42. # draw label
  43. text = "{} {:.4f}".format(dt["type"], dt["score"])
  44. tw, th = imagedraw_textsize_c(draw, text)
  45. draw.rectangle(
  46. [(xmin + 1, ymin - th), (xmin + tw + 1, ymin)], fill=color)
  47. draw.text((xmin + 1, ymin - th), text, fill=(255, 255, 255))
  48. return im
  49. def get_color_map_list(num_classes):
  50. """
  51. Args:
  52. num_classes (int): number of class
  53. Returns:
  54. color_map (list): RGB color list
  55. """
  56. color_map = num_classes * [0, 0, 0]
  57. for i in range(0, num_classes):
  58. j = 0
  59. lab = i
  60. while lab:
  61. color_map[i * 3] |= (((lab >> 0) & 1) << (7 - j))
  62. color_map[i * 3 + 1] |= (((lab >> 1) & 1) << (7 - j))
  63. color_map[i * 3 + 2] |= (((lab >> 2) & 1) << (7 - j))
  64. j += 1
  65. lab >>= 3
  66. color_map = [color_map[i:i + 3] for i in range(0, len(color_map), 3)]
  67. return color_map
  68. def imagedraw_textsize_c(draw, text):
  69. if int(PIL.__version__.split('.')[0]) < 10:
  70. tw, th = draw.textsize(text)
  71. else:
  72. left, top, right, bottom = draw.textbbox((0, 0), text)
  73. tw, th = right - left, bottom - top
  74. return tw, th