Phần 1 - Xử lý bộ dữ liệu cho mô hình phát hiện đối tượng (Object Detection)
Mô hình YOLO là một mô hình rất phổ biến trong nhận diện hình ảnh vì tính tiện dụng của mình.
Phiên bản đầu tiên của mô hình này chủ yếu sử dụng kiến trúc CNN. Kiến trúc CNN được đề cập chi tiết tại đây.
Để có thể chuẩn bị dữ liệu cho mình này, bạn cần nắm được đầu ra của mô hình và lập trình sao cho với các bộ dữ liệu khác nhau, bạn có thể cung cấp cấu trúc mà YOLO yêu cầu.
Dưới đây là một ví dụ tiền xử lý nhãn cho bộ dữ liệu Pascal VOC
1) Giới thiệu bộ dữ liệu Pascal VOC
Pascal VOC là một bộ dữ liệu nổi tiếng cung cấp cho chúng ta dữ liệu phục vụ cho việc nhận diện đối tượng trong ảnh. Trong bài này chúng ta sẽ sử dụng dữ liệu từ năm 2017 để thực hành.
Một cặp dữ liệu của VOC bao gồm 2 phần
Hình ảnh dưới dạng Tensor
Nhãn của ảnh này dưới dạng như sau
{
"annotation": {
"folder": "VOC2007",
"filename": "000219.jpg",
"source": {
"database": "The VOC2007 Database",
"annotation": "PASCAL VOC2007",
"image": "flickr",
"flickrid": "321854556",
},
"owner": {"flickrid": "momimdr", "name": "?"},
"size": {"width": "333", "height": "500", "depth": "3"},
"segmented": "0",
"object": [
{
"name": "motorbike",
"pose": "Left",
"truncated": "0",
"difficult": "0",
"bndbox": {"xmin": "120", "ymin": "333", "xmax": "310", "ymax": "464"},
}
],
}
}
Object chính là phần bounding box của bức ảnh mà chúng ta cần.
{
"object": [
{
"name": "motorbike",
"pose": "Left",
"truncated": "0",
"difficult": "0",
"bndbox": {"xmin": "120", "ymin": "333", "xmax": "310", "ymax": "464"},
}
],
}
Object này chính là chứa khung đỏ bao quanh (bounding box) chiếc xe máy mà chúng ta nhìn thấy ảnh bên trên. Cùng phân tích xem các giá trị xmin, ymin, xmax, ymax thể hiện ý nghĩa như thế nào của khung?
2) Scale ảnh về kích cỡ 448 x 448
Ảnh sẽ được resize ở kích thước bất kỳ về một Tensor có cỡ 3 x 448 x 448 với
3 lớp đại diện cho 3 màu đỏ, xanh lục, xanh dương
448 là chiều dài
448 là chiều cào
Cách load dữ liệu và resize ngay sau đó rất đơn giản, bạn có thể load trực tiếp từ thư viện Pytorch
dataset = VOCDetection(
root='data',
year='2007',
image_set=('train' if set_type == 'train' else 'val'),
download=True,
transform=T.Compose([
T.ToTensor(),
T.Resize((448, 448)
)
])
)
Hàm resize về cỡ 448 x 448 đã nằm ngay trong phần load dữ liệu này.
3) Bounding box là gì
Bounding box là hình chữ nhật bao quanh vật thể được xác lập bởi 2 điểm.
Điểm min: Điểm nằm bên trái góc trên của bounding box
Điểm max: Điểm nằm bên phải góc dưới của bounding box
Trong trường hợp này bạn cần chú ý:
Trục x nằm ngang bên trên
Trục y nằm dọc bên tay trái
Điểm min có giá trị theo trục x là xmin = 161 và theo trục y là ymin = 298
Điểm max có giá trị theo trục x là xmax = 417 và theo trục y là ymax = 415.
4) Giãn Bounding Box
Tuy nhiên khi thay đổi kích cỡ của ảnh thì cũng cần thay đổi kích cỡ của bouding box vì thế trong trong trường hợp này ta sẽ scale cả bouding box tương ứng.
def get_bounding_boxes(label):
width, height = get_dimensions(label)
x_scale = config.IMAGE_SIZE[0] / width
y_scale = config.IMAGE_SIZE[1] / height
boxes = []
objects = label['annotation']['object']
for obj in objects:
box = obj['bndbox']
coords = (
int(int(box['xmin']) * x_scale),
int(int(box['xmax']) * x_scale),
int(int(box['ymin']) * y_scale),
int(int(box['ymax']) * y_scale)
)
name = obj['name']
boxes.append((name, coords))
return boxes
Nhìn hàm trên bạn có thể thấy ta sẽ:
Tìm độ giãn x_scale theo chiều dài của ảnh mới (448) và chiều dài của ảnh cũ
Tìm độ giản y_scale theo chiều cao của ảnh mới (448) và chiều cao của ảnh cũ
Sau khi có hai độ giãn này
Giãn các giá trị xmin, xmax theo độ giãn x_scale
Giãn các giá trị ymin, ymax theo độ giãn y_scale
5) Chia ảnh thành Grid
Thuật toán YOLO sẽ chia ảnh thành một Grid cỡ S x S và nếu trong trường hợp này S = 7 thì Grid sẽ trông như thế này:
Tức là ta sẽ có 7x7 = 49 ô.
Từ mỗi ô này, YOLO sẽ cố gắng vẽ ra được các bounding box khớp nhất với bounding box màu đỏ nhãn. Ô này sẽ chứa tâm của bounding box Yolo học.
Chi tiết Đầu ra của Yolo sẽ được mô phỏng dưới hình dạng này:
Chi tiết sẽ được giải thích tại phần hai sẽ được công bố vào ngày mai 07/11/2023. Bạn cũng chờ đón nhé.