Từ Dictionary Python đến "Mắt Thần" AI: Giải Mã IoU và NMS

Khánh PhùngKhánh Phùng
8 min read

Bạn lướt qua album ảnh trên điện thoại, và thật kỳ diệu, ứng dụng tự động nhận diện và gom nhóm tất cả ảnh của một người bạn vào cùng một thư mục. Bạn xem một video về xe tự lái, và nó có thể "nhìn thấy", vẽ những chiếc hộp gọn gàng xung quanh người đi đường, xe cộ, và biển báo giao thông trong thời gian thực.

"Phép thuật" đằng sau những công nghệ này là gì? Liệu có phải là những thuật toán AI cao siêu, phức tạp đến mức chúng ta không thể hiểu nổi?

Sự thật là, những hệ thống tinh vi đó được xây dựng trên những nền tảng vô cùng quen thuộc. Trong bài viết này, chúng ta sẽ không chỉ học định nghĩa, mà sẽ cùng nhau "mổ xẻ" tận gốc rễ, xây dựng lại từng thuật toán từ con số không, chỉ với những kiến thức Python cơ bản bạn đã biết.

Hãy cùng thực hiện một hành trình khám phá: từ "viên gạch" Dictionary quen thuộc, đến việc giải mã hai khái niệm cốt lõi trong ngành thị giác máy tính: IoU (Intersection over Union)NMS (Non-Maximum Suppression).

1. Viên Gạch Nền Tảng: Sức Mạnh Của Python Dictionary

Trước khi xây dựng một tòa nhà chọc trời, chúng ta cần những viên gạch vững chắc. Trong Python, Dictionary chính là một trong những viên gạch đa năng và hiệu quả nhất.

Khác với List chỉ có thể truy cập bằng chỉ số (index), Dictionary cho phép chúng ta lưu trữ và truy xuất dữ liệu thông qua các cặp key-value. Điều này không chỉ làm cho code của chúng ta dễ đọc hơn mà còn cực kỳ nhanh chóng.

Góc kỹ thuật: Tốc độ truy xuất trung bình của Dictionary là O(1), tức là gần như tức thời, bất kể dictionary có lớn đến đâu. Đây là một ưu thế vượt trội so với việc phải duyệt qua một List (tốc độ O(n)) để tìm một phần tử.

Hãy xem xét ví dụ sau:

# Dùng dictionary để lưu thông tin chi tiết một bounding box
# bounding_box là tên gọi của chiếc hộp AI vẽ ra
bounding_box = {
    "label": "cat",
    "confidence": 0.95,
    "coordinates": {
        "x1": 50, # Tọa độ x của góc trên, bên trái
        "y1": 70, # Tọa độ y của góc trên, bên trái
        "x2": 250, # Tọa độ x của góc dưới, bên phải
        "y2": 280  # Tọa độ y của góc dưới, bên phải
    }
}

# Truy xuất thông tin rất trực quan
print(f"AI tìm thấy một con {bounding_box['label']}!")
print(f"Độ tự tin của AI là: {bounding_box['confidence'] * 100}%")

Như bạn thấy, chúng ta đã có thể "đóng gói" toàn bộ thông tin về một vật thể mà AI "nhìn" thấy vào một biến dictionary duy nhất. Đây chính là cầu nối để đi vào thế giới của AI.

2. Phép Thuật Thứ Nhất: IoU - "Chúng Ta Có Thực Sự Đồng Lòng?"

IoU là viết tắt của Intersection over Union. Đây là một trong những chỉ số quan trọng và phổ biến nhất trong các bài toán nhận diện vật thể.

Tình huống thực tế: Hãy tưởng tượng bạn và một người bạn cùng được giao nhiệm vụ vẽ một cái khung quanh con mèo trong ảnh. Bạn vẽ hộp màu xanh, bạn của bạn vẽ hộp màu đỏ. IoU chính là một con số để "chấm điểm" xem hai cái hộp của hai bạn có khớp nhau nhiều hay không. Nếu hai hộp khớp hoàn toàn, điểm IoU là 1. Nếu chúng không chạm vào nhau, điểm IoU là 0.

Công thức của nó là: $$ IoU = \frac{\text{Diện tích vùng giao nhau (Intersection)}}{\text{Diện tích vùng hợp lại (Union)}} $$

Gợi ý: Bạn nên tải hình ảnh này về và upload trực tiếp lên Hashnode để đảm bảo bài viết không bị mất ảnh.

Bây giờ, hãy "mổ xẻ" cách tính toán.

Bước 1: Tìm diện tích vùng giao nhau (Intersection)

Để tìm ra chiếc hộp giao nhau, chúng ta cần tìm 2 góc của nó:

  • Góc trên-trái (inter_x1, inter_y1): sẽ là điểm có tọa độ lớn nhất trong hai góc trên-trái của hai hộp ban đầu.

  • Góc dưới-phải (inter_x2, inter_y2): sẽ là điểm có tọa độ nhỏ nhất trong hai góc dưới-phải.

Bước 2: Tính diện tích vùng hợp lại (Union)

Toán học cơ bản cho chúng ta biết: Diện tích(Hợp) = Diện tích(Hộp A) + Diện tích(Hộp B) - Diện tích(Giao) Tại sao phải trừ đi phần giao? Bởi vì nếu chỉ cộng diện tích hai hộp lại, phần giao nhau sẽ bị tính hai lần!

Giờ hãy biến những logic này thành code Python.

Python

def calculate_iou(boxA, boxB):
    """
    Tính chỉ số IoU giữa 2 bounding box.
    Mỗi box là một dictionary có keys: "x1", "y1", "x2", "y2".
    """
    # 1. Xác định tọa độ (x, y) của vùng giao nhau
    inter_x1 = max(boxA["x1"], boxB["x1"])
    inter_y1 = max(boxA["y1"], boxB["y1"])
    inter_x2 = min(boxA["x2"], boxB["x2"])
    inter_y2 = min(boxA["y2"], boxB["y2"])

    # 2. Tính diện tích vùng giao nhau
    # Chiều rộng và chiều cao của vùng giao nhau
    inter_width = inter_x2 - inter_x1
    inter_height = inter_y2 - inter_y1

    # Nếu chiều rộng hoặc chiều cao âm, tức là 2 box không giao nhau
    if inter_width <= 0 or inter_height <= 0:
        return 0.0

    intersection_area = inter_width * inter_height

    # 3. Tính diện tích của từng bounding box
    boxA_area = (boxA["x2"] - boxA["x1"]) * (boxA["y2"] - boxA["y1"])
    boxB_area = (boxB["x2"] - boxB["x1"]) * (boxB["y2"] - boxB["y1"])

    # 4. Tính diện tích vùng hợp lại
    union_area = float(boxA_area + boxB_area - intersection_area)

    # 5. Tính và trả về chỉ số IoU
    iou = intersection_area / union_area

    # Đảm bảo iou nằm trong khoảng [0, 1]
    return max(0.0, min(1.0, iou))

# ---- Ví dụ minh họa ----
box_predict = {"x1": 50, "y1": 50, "x2": 150, "y2": 150} # Hộp AI dự đoán
box_ground_truth = {"x1": 70, "y1": 60, "x2": 170, "y2": 180} # Hộp đúng (đáp án)

iou_score = calculate_iou(box_predict, box_ground_truth)
print(f"Chỉ số IoU là: {iou_score:.4f}")

# Output: Chỉ số IoU là: 0.4615
# Ta có thể kết luận dự đoán của AI là "khá tốt" (gần 0.5)

3. Phép Thuật Thứ Hai: NMS - "Vị Giám Khảo" Khó Tính

NMS là viết tắt của Non-Maximum Suppression (tạm dịch: Đàn áp những thứ không phải cực đại).

Tình huống thực tế: Mô hình AI sau khi "quét" qua một bức ảnh thường rất "hăng hái". Nó có thể phát hiện ra 1 con chó nhưng lại vẽ tới 17 cái bounding box chồng chéo lên nhau quanh con chó đó, mỗi box có một độ tự tin khác nhau. Chúng ta không muốn 17 kết quả, chúng ta chỉ muốn 1 kết quả duy nhất và "xịn" nhất.

Analogy: Hãy coi NMS là vòng loại của một cuộc thi sắc đẹp dành cho các bounding box.

  • Giám khảo: Là chính thuật toán NMS.

  • Tiêu chí chấm điểm: Độ tự tin (confidence score).

  • Luật chơi: Chỉ có "hoa hậu" (box có điểm tự tin cao nhất) mới được giữ lại. Các "á hậu" có gương mặt "na ná" hoa hậu (tức là có IoU cao với hoa hậu) sẽ bị loại để tránh gây nhầm lẫn cho khán giả.

Thuật toán NMS hoạt động như sau:

  1. Nhận vào một danh sách tất cả các bounding box và một ngưỡng IoU (ví dụ iou_threshold = 0.5).

  2. Sắp xếp danh sách này theo thứ tự độ tự tin (confidence score) giảm dần.

  3. Tạo một danh sách rỗng để chứa kết quả cuối cùng.

  4. Bắt đầu một vòng lặp: a. Lấy box có độ tự tin cao nhất ra khỏi danh sách và cho nó vào danh sách kết quả. b. Tính IoU của box vừa lấy với tất cả các box còn lại trong danh sách. c. Loại bỏ tất cả các box có IoU lớn hơn iou_threshold.

  5. Lặp lại bước 4 cho đến khi danh sách ban đầu không còn box nào.

  6. Trả về danh sách kết quả.

Hãy xem một ví dụ cụ thể:

Giả sử AI dự đoán 4 box cho cùng một vật thể:

  • Box A (confidence: 0.98)

  • Box B (confidence: 0.90)

  • Box C (confidence: 0.85)

  • Box D (confidence: 0.70)

Và ta đặt iou_threshold = 0.6.

  • Vòng 1:

    • Box A có điểm cao nhất -> cho A vào kết quả.

    • Tính: IoU(A, B) = 0.8, IoU(A, C) = 0.2, IoU(A, D) = 0.7.

    • IoU(A, B)IoU(A, D) > 0.6 -> Loại B và D.

    • Danh sách giờ chỉ còn: [C]

  • Vòng 2:

    • Box C là box duy nhất còn lại -> cho C vào kết quả.
  • Kết quả cuối cùng: [A, C]. Điều này có nghĩa là, NMS đã xác định rằng có thể có 2 vật thể riêng biệt trong ảnh (vì A và C không bị loại lẫn nhau).

Kết Luận: Vẻ Đẹp Của Sự Đơn Giản

Hành trình chúng ta vừa đi qua không chỉ là về code. Nó là minh chứng cho một nguyên lý đẹp đẽ trong khoa học và kỹ thuật: Những hệ thống phức tạp và kỳ diệu nhất thường được xây dựng từ những nguyên lý nền tảng vô cùng vững chắc và dễ hiểu.

Từ một dictionary đơn giản, chúng ta đã có thể biểu diễn được một khái niệm trong AI. Từ những phép toán cộng trừ nhân chia cơ bản, chúng ta đã xây dựng được IoU để đo lường thế giới thực. Và từ những vòng lặp và điều kiện if-else, chúng ta đã tạo ra NMS để giúp AI đưa ra quyết định thông minh hơn.

Lần tới khi bạn trầm trồ trước một công nghệ AI, hãy nhớ rằng đằng sau nó là vô số những "viên gạch" cơ bản như thế này. Việc nắm vững kiến thức nền tảng không bao giờ là thừa, vì nó chính là chìa khóa để bạn có thể tự mình xây dựng nên những "tòa nhà" còn vĩ đại hơn trong tương lai.

Bạn có nghĩ ra ứng dụng nào khác của IoU và NMS trong cuộc sống không? Hay có 'viên gạch' cơ bản nào khác mà bạn thấy đã xây nên những 'tòa nhà' kỳ vĩ? Hãy chia sẻ suy nghĩ của bạn ở phần bình luận nhé!

0
Subscribe to my newsletter

Read articles from Khánh Phùng directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Khánh Phùng
Khánh Phùng