# Phát hiện đối tượng

Mô hình phát hiện đối tượng xác định một đối tượng trong hình ảnh, và bộ dữ liệu phát hiện đối tượng được sử dụng cho các ứng dụng như lái xe tự hành và phát hiện các mối nguy hiểm tự nhiên như cháy rừng. Hướng dẫn này sẽ cho bạn thấy cách áp dụng các phép biến đổi cho một bộ dữ liệu phát hiện đối tượng theo [hướng dẫn](https://albumentations.ai/docs/examples/example_bboxes/) từ [Albumentations](https://albumentations.ai/docs/).

Để chạy các ví dụ này, hãy đảm bảo bạn đã cài đặt các phiên bản mới nhất của [albumentations](https://albumentations.ai/docs/) và [cv2](https://docs.opencv.org/4.10.0/):

```bash
pip install -U albumentations opencv-python
```

Trong ví dụ này, bạn sẽ sử dụng bộ dữ liệu [`cppe-5`](https://huggingface.co/datasets/rishitdagli/cppe-5) để nhận diện thiết bị bảo hộ cá nhân y tế (PPE) trong bối cảnh đại dịch COVID-19.

Tải bộ dữ liệu và xem một ví dụ:

```py
>>> from datasets import load_dataset

>>> ds = load_dataset("rishitdagli/cppe-5")
>>> example = ds['train'][0]
>>> example
{'height': 663,
 'image': <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=943x663 at 0x7FC3DC756250>,
 'image_id': 15,
 'objects': {'area': [3796, 1596, 152768, 81002],
  'bbox': [[302.0, 109.0, 73.0, 52.0],
   [810.0, 100.0, 57.0, 28.0],
   [160.0, 31.0, 248.0, 616.0],
   [741.0, 68.0, 202.0, 401.0]],
  'category': [4, 4, 0, 0],
  'id': [114, 115, 116, 117]},
 'width': 943}
```

Bộ dữ liệu có các trường sau:

- `image`: đối tượng PIL.Image.Image chứa hình ảnh.
- `image_id`: ID của hình ảnh.
- `height`: Chiều cao của hình ảnh.
- `width`: Độ rộng của hình ảnh.
- `objects`: Một từ điển chứa các siêu dữ liệu hộp bao quanh cho các đối tượng trong hình ảnh:
  - `id`: ID của chú thích.
  - `area`: Diện tích của hộp bao.
  - `bbox`: Hộp bao quanh đối tượng (theo định dạng [coco](https://albumentations.ai/docs/3-basic-usage/bounding-boxes-augmentations/#understanding-bounding-box-formats)).
  - `category`: Danh mục của đối tượng, với các giá trị có thể bao gồm `Coverall (0)`, `Face_Shield (1)`, `Gloves (2)`, `Goggles (3)` và `Mask (4)`.

Bạn có thể trực quan hóa `bboxes` trên ảnh bằng một số tiện ích torch nội bộ. Để làm điều đó, bạn cần tham chiếu tính năng [ClassLabel](/docs/datasets/main/vi/package_reference/main_classes#datasets.ClassLabel) liên quan đến các ID danh mục để tra cứu các nhãn chuỗi:

```py
>>> import torch
>>> from torchvision.ops import box_convert
>>> from torchvision.utils import draw_bounding_boxes
>>> from torchvision.transforms.functional import pil_to_tensor, to_pil_image

>>> categories = ds['train'].features['objects'].feature['category']

>>> boxes_xywh = torch.tensor(example['objects']['bbox'])
>>> boxes_xyxy = box_convert(boxes_xywh, 'xywh', 'xyxy')
>>> labels = [categories.int2str(x) for x in example['objects']['category']]
>>> to_pil_image(
...     draw_bounding_boxes(
...         pil_to_tensor(example['image']),
...         boxes_xyxy,
...         colors="red",
...         labels=labels,
...     )
... )
```

    

Với `albumentations`, bạn có thể áp dụng các phép biến đổi ảnh hưởng đến hình ảnh đồng thời cập nhật `bboxes` cho phù hợp. Trong trường hợp này, hình ảnh được thay đổi kích thước thành (480, 480), lật ngang và tăng độ sáng.

```py
>>> import albumentations
>>> import numpy as np

>>> transform = albumentations.Compose([
...     albumentations.Resize(480, 480),
...     albumentations.HorizontalFlip(p=1.0),
...     albumentations.RandomBrightnessContrast(p=1.0),
... ], bbox_params=albumentations.BboxParams(format='coco',  label_fields=['category']))

>>> image = np.array(example['image'])
>>> out = transform(
...     image=image,
...     bboxes=example['objects']['bbox'],
...     category=example['objects']['category'],
... )
```

Bây giờ khi bạn trực quan hóa kết quả, hình ảnh nên bị lật, nhưng `bboxes` vẫn phải ở đúng vị trí.

```py
>>> image = torch.tensor(out['image']).permute(2, 0, 1)
>>> boxes_xywh = torch.stack([torch.tensor(x) for x in out['bboxes']])
>>> boxes_xyxy = box_convert(boxes_xywh, 'xywh', 'xyxy')
>>> labels = [categories.int2str(x) for x in out['category']]
>>> to_pil_image(
...     draw_bounding_boxes(
...         image,
...         boxes_xyxy,
...         colors='red',
...         labels=labels
...     )
... )
```

    

Tạo một hàm để áp dụng phép biến đổi vào một lô các ví dụ:

```py
>>> def transforms(examples):
...     images, bboxes, categories = [], [], []
...     for image, objects in zip(examples['image'], examples['objects']):
...         image = np.array(image.convert("RGB"))
...         out = transform(
...             image=image,
...             bboxes=objects['bbox'],
...             category=objects['category']
...         )
...         images.append(torch.tensor(out['image']).permute(2, 0, 1))
...         bboxes.append(torch.tensor(out['bboxes']))
...         categories.append(out['category'])
...     return {'image': images, 'bbox': bboxes, 'category': categories}
```

Sử dụng hàm [set_transform()](/docs/datasets/main/vi/package_reference/main_classes#datasets.Dataset.set_transform) để áp dụng transform theo thời gian thực, giúp tiết kiệm dung lượng ổ đĩa. Tính ngẫu nhiên của data augmentation có thể trả về một hình ảnh khác nếu bạn truy cập cùng một ví dụ hai lần. Điều này đặc biệt hữu ích khi huấn luyện mô hình qua nhiều epoch.

```py
>>> ds['train'].set_transform(transforms)
```

Bạn có thể kiểm tra xem transform có hoạt động không bằng cách trực quan hóa ví dụ thứ 10:

```py
>>> example = ds['train'][10]
>>> to_pil_image(
...     draw_bounding_boxes(
...         example['image'],
...         box_convert(example['bbox'], 'xywh', 'xyxy'),
...         colors='red',
...         labels=[categories.int2str(x) for x in example['category']]
...     )
... )
```

    

> [!TIP]
> Giờ đây, khi bạn đã biết cách xử lý một tập dữ liệu cho phát hiện đối tượng, hãy tìm hiểu [cách huấn luyện một mô hình phát hiện đối tượng](https://colab.research.google.com/github/NielsRogge/Transformers-Tutorials/blob/master/YOLOS/Fine_tuning_YOLOS_for_object_detection_on_custom_dataset_(balloon).ipynb) và sử dụng nó để suy luận.

