ultralytics 8.0.75 fixes and updates (#1967)

Co-authored-by: Laughing-q <1185102784@qq.com>
Co-authored-by: Jonathan Rayner <jonathan.j.rayner@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Glenn Jocher
2023-04-13 02:04:10 +02:00
committed by GitHub
parent e5cb35edfc
commit 48c4483795
9 changed files with 128 additions and 98 deletions

View File

@ -21,7 +21,7 @@ class BaseTensor(SimpleClass):
"""
Attributes:
tensor (torch.Tensor): A tensor.
data (torch.Tensor): Base tensor.
orig_shape (tuple): Original image size, in the format (height, width).
Methods:
@ -31,20 +31,14 @@ class BaseTensor(SimpleClass):
to(): Returns a copy of the tensor with the specified device and dtype.
"""
def __init__(self, tensor, orig_shape) -> None:
super().__init__()
assert isinstance(tensor, torch.Tensor)
self.tensor = tensor
def __init__(self, data, orig_shape) -> None:
self.data = data
self.orig_shape = orig_shape
@property
def shape(self):
return self.data.shape
@property
def data(self):
return self.tensor
def cpu(self):
return self.__class__(self.data.cpu(), self.orig_shape)
@ -164,7 +158,6 @@ class Results(SimpleClass):
font_size=None,
font='Arial.ttf',
pil=False,
example='abc',
img=None,
img_gpu=None,
kpt_line=True,
@ -183,7 +176,6 @@ class Results(SimpleClass):
font_size (float, optional): The font size of the text. If None, it is scaled to the image size.
font (str): The font to use for the text.
pil (bool): Whether to return the image as a PIL Image.
example (str): An example string to display. Useful for indicating the expected format of the output.
img (numpy.ndarray): Plot to another image. if not, plot to original image.
img_gpu (torch.Tensor): Normalized image in gpu with shape (1, 3, 640, 640), for faster mask plotting.
kpt_line (bool): Whether to draw lines connecting keypoints.
@ -201,12 +193,16 @@ class Results(SimpleClass):
conf = kwargs['show_conf']
assert type(conf) == bool, '`show_conf` should be of boolean type, i.e, show_conf=True/False'
annotator = Annotator(deepcopy(self.orig_img if img is None else img), line_width, font_size, font, pil,
example)
names = self.names
annotator = Annotator(deepcopy(self.orig_img if img is None else img),
line_width,
font_size,
font,
pil,
example=names)
pred_boxes, show_boxes = self.boxes, boxes
pred_masks, show_masks = self.masks, masks
pred_probs, show_probs = self.probs, probs
names = self.names
keypoints = self.keypoints
if pred_masks and show_masks:
if img_gpu is None:
@ -236,13 +232,13 @@ class Results(SimpleClass):
def verbose(self):
"""
Return log string for each tasks.
Return log string for each task.
"""
log_string = ''
probs = self.probs
boxes = self.boxes
if len(self) == 0:
return log_string if probs is not None else log_string + '(no detections), '
return log_string if probs is not None else f'{log_string}(no detections), '
if probs is not None:
n5 = min(len(self.names), 5)
top5i = probs.argsort(0, descending=True)[:n5].tolist() # top 5 indices
@ -346,26 +342,26 @@ class Boxes(BaseTensor):
boxes = boxes[None, :]
n = boxes.shape[-1]
assert n in (6, 7), f'expected `n` in [6, 7], but got {n}' # xyxy, (track_id), conf, cls
super().__init__(boxes, orig_shape)
self.is_track = n == 7
self.boxes = boxes
self.orig_shape = torch.as_tensor(orig_shape, device=boxes.device) if isinstance(boxes, torch.Tensor) \
else np.asarray(orig_shape)
@property
def xyxy(self):
return self.boxes[:, :4]
return self.data[:, :4]
@property
def conf(self):
return self.boxes[:, -2]
return self.data[:, -2]
@property
def cls(self):
return self.boxes[:, -1]
return self.data[:, -1]
@property
def id(self):
return self.boxes[:, -3] if self.is_track else None
return self.data[:, -3] if self.is_track else None
@property
@lru_cache(maxsize=2) # maxsize 1 should suffice
@ -386,8 +382,9 @@ class Boxes(BaseTensor):
LOGGER.info('results.pandas() method not yet implemented')
@property
def data(self):
return self.boxes
def boxes(self):
LOGGER.warning("WARNING ⚠️ 'Boxes.boxes' is deprecated. Use 'Boxes.data' instead.")
return self.data
class Masks(BaseTensor):
@ -416,8 +413,7 @@ class Masks(BaseTensor):
def __init__(self, masks, orig_shape) -> None:
if masks.ndim == 2:
masks = masks[None, :]
self.masks = masks # N, h, w
self.orig_shape = orig_shape
super().__init__(masks, orig_shape)
@property
@lru_cache(maxsize=1)
@ -432,17 +428,18 @@ class Masks(BaseTensor):
def xyn(self):
# Segments (normalized)
return [
ops.scale_coords(self.masks.shape[1:], x, self.orig_shape, normalize=True)
for x in ops.masks2segments(self.masks)]
ops.scale_coords(self.data.shape[1:], x, self.orig_shape, normalize=True)
for x in ops.masks2segments(self.data)]
@property
@lru_cache(maxsize=1)
def xy(self):
# Segments (pixels)
return [
ops.scale_coords(self.masks.shape[1:], x, self.orig_shape, normalize=False)
for x in ops.masks2segments(self.masks)]
ops.scale_coords(self.data.shape[1:], x, self.orig_shape, normalize=False)
for x in ops.masks2segments(self.data)]
@property
def data(self):
return self.masks
def masks(self):
LOGGER.warning("WARNING ⚠️ 'Masks.masks' is deprecated. Use 'Masks.data' instead.")
return self.data