tbs_detection_pipeline.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. # Copyright (c) Alibaba, Inc. and its affiliates.
  2. import colorsys
  3. import os
  4. from typing import Any, Dict
  5. import cv2
  6. import numpy as np
  7. import torch
  8. from PIL import Image, ImageDraw, ImageFile, ImageFont
  9. from modelscope.metainfo import Pipelines
  10. from modelscope.outputs import OutputKeys
  11. from modelscope.pipelines.base import Input, Pipeline
  12. from modelscope.pipelines.builder import PIPELINES
  13. from modelscope.pipelines.cv.tbs_detection_utils.utils import (_get_anchors,
  14. generate,
  15. post_process)
  16. from modelscope.preprocessors import LoadImage
  17. from modelscope.utils.constant import Tasks
  18. from modelscope.utils.logger import get_logger
  19. ImageFile.LOAD_TRUNCATED_IMAGES = True
  20. logger = get_logger()
  21. __all__ = ['TBSDetectionPipeline']
  22. @PIPELINES.register_module(
  23. Tasks.image_object_detection, module_name=Pipelines.tbs_detection)
  24. class TBSDetectionPipeline(Pipeline):
  25. """ TBS Detection Pipeline.
  26. Example:
  27. ```python
  28. >>> from modelscope.pipelines import pipeline
  29. >>> tbs_detect = pipeline(Tasks.image_object_detection, model='landingAI/LD_CytoBrainCerv')
  30. >>> tbs_detect(input='data/test/images/tbs_detection.jpg')
  31. {
  32. "boxes": [
  33. [
  34. 446.9007568359375,
  35. 36.374977111816406,
  36. 907.0919189453125,
  37. 337.439208984375
  38. ],
  39. [
  40. 454.3310241699219,
  41. 336.08477783203125,
  42. 921.26904296875,
  43. 641.7871704101562
  44. ]
  45. ],
  46. "labels": [
  47. ["Positive"]
  48. ],
  49. "scores": [
  50. 0.9296008944511414,
  51. 0.9260380268096924
  52. ]
  53. }
  54. >>> #
  55. ```
  56. """
  57. _defaults = {
  58. 'class_names': ['positive'],
  59. 'model_image_size': (416, 416, 3),
  60. 'confidence': 0.5,
  61. 'iou': 0.3,
  62. }
  63. @classmethod
  64. def get_defaults(cls, n):
  65. if n in cls._defaults:
  66. return cls._defaults[n]
  67. else:
  68. return "Unrecognized attribute name '" + n + "'"
  69. def __init__(self, model: str, **kwargs):
  70. """
  71. model: model id on modelscope hub.
  72. """
  73. super().__init__(model=model, auto_collate=False, **kwargs)
  74. self.__dict__.update(self._defaults)
  75. self.anchors = _get_anchors(self)
  76. generate(self)
  77. def preprocess(self, input: Input) -> Dict[str, Any]:
  78. """
  79. Detect objects (bounding boxes) in the image(s) passed as inputs.
  80. Args:
  81. input (`Image` or `List[Image]`):
  82. The pipeline handles three types of images:
  83. - A string containing an HTTP(S) link pointing to an image
  84. - A string containing a local path to an image
  85. - An image loaded in PIL or opencv directly
  86. The pipeline accepts either a single image or a batch of images. Images in a batch must all be in the
  87. same format.
  88. Return:
  89. A dictionary of result or a list of dictionary of result. If the input is an image, a dictionary
  90. is returned. If input is a list of image, a list of dictionary is returned.
  91. The dictionary contain the following keys:
  92. - **scores** (`List[float]`) -- The detection score for each card in the image.
  93. - **boxes** (`List[float]) -- The bounding boxe [x1, y1, x2, y2] of detected objects in in image's
  94. original size.
  95. - **labels** (`List[str]`, optional) -- The boxes's class_names of detected object in image.
  96. """
  97. img = LoadImage.convert_to_ndarray(input)
  98. img = img.astype(float)
  99. result = {'img': img, 'img_path': input}
  100. return result
  101. def forward(self, input: Dict[str, Any]) -> Dict[str, Any]:
  102. img = input['img'].astype(np.uint8)
  103. img = cv2.resize(img, (416, 416))
  104. img = img.astype(np.float32)
  105. tmp_inp = np.transpose(img / 255.0, (2, 0, 1))
  106. tmp_inp = torch.from_numpy(tmp_inp).type(torch.FloatTensor)
  107. img = torch.unsqueeze(tmp_inp, dim=0)
  108. model_path = os.path.join(self.model, 'pytorch_yolov4.pt')
  109. model = torch.load(model_path, weights_only=True)
  110. outputs = model(img.cuda())
  111. result = {'data': outputs, 'img_path': input['img_path']}
  112. return result
  113. def postprocess(self, input: Dict[str, Any], *args,
  114. **kwargs) -> Dict[str, Any]:
  115. bboxes, scores = post_process(self, input['data'], input['img_path'])
  116. if bboxes is None:
  117. outputs = {OutputKeys.SCORES: [], OutputKeys.BOXES: []}
  118. return outputs
  119. outputs = {
  120. OutputKeys.SCORES: scores.tolist(),
  121. OutputKeys.LABELS: ['Positive'],
  122. OutputKeys.BOXES: bboxes
  123. }
  124. return outputs