ภาพปก Intersection over Union (IoU) ในงาน Object Detection

1. 🎯 ตอนที่ 43: ไม้บรรทัดวัดความแม่น! เจาะลึก IoU

สวัสดีครับน้องๆ วิศวกรสาย Vision และนักพัฒนาที่รักทุกท่าน! ชงกาแฟให้พร้อมแล้วมาลุยกันต่อครับ

ในตอนที่แล้วเราได้สอนให้ AI รู้จักการตีกรอบสี่เหลี่ยม หรือ Bounding Box ล้อมรอบวัตถุกันไปแล้ว แต่คำถามโลกแตกที่ตามมาเวลาเราเอาโมเดลไปทดสอบคือ… “เราจะรู้ได้อย่างไรว่ากรอบที่ AI ตีมาให้ มัน ‘แม่น’ แค่ไหน?”

ถ้าน้องใช้แค่ตาเปล่ามอง บางทีกรอบมันอาจจะเบี้ยวไปทางซ้ายนิด ขวาหน่อย การจะใช้ไม้บรรทัดอย่าง Mean Squared Error (MSE) มาวัดพิกัดตรงๆ ก็มักจะไม่สะท้อนความเป็นจริงและให้ผลลัพธ์ที่ไม่ค่อยดีนักครับ ในบริบทที่กว้างขึ้นของงาน Object Detection วงการคอมพิวเตอร์วิทัศน์จึงได้สถาปนา “มาตรฐานทองคำ” ขึ้นมาตัวหนึ่ง เพื่อใช้วัดความทับซ้อนของพื้นที่ เราเรียกมันว่า Intersection over Union หรือ IoU ครับ วันนี้พี่จะพาไปแกะกล่องดูว่า ทำไมสมการคณิตศาสตร์เรียบง่ายแค่นี้ ถึงกลายเป็นหัวใจสำคัญที่กำหนดชะตากรรมของโมเดล AI ทั่วโลก!

2. 📖 เปิดฉาก (The Hook)

ลองจินตนาการว่าน้องกำลังเล่นเกม “แปะสติ๊กเกอร์ให้ตรงรอย” สมมติว่ามีสติ๊กเกอร์เป้าหมาย (Ground Truth) แปะอยู่บนกระดาน แล้วน้องต้องหลับตาเอาสติ๊กเกอร์อีกแผ่น (Prediction) ไปแปะทับให้สนิทที่สุด!

ถ้าน้องแปะเบี้ยวไปนิดเดียว ขอบมันก็จะเหลื่อมกันใช่ไหมครับ? พื้นที่ตรงกลางที่สติ๊กเกอร์สองแผ่นซ้อนทับกันพอดี นั่นแหละคือ “Intersection (จุดตัด)” ส่วนพื้นที่ทั้งหมดที่เกิดจากสติ๊กเกอร์ทั้งสองแผ่นรวมกัน (โดยไม่นับซ้ำ) นั่นคือ “Union (ผลรวม)”

ในโลกของ AI เราวัดความเก่งของโมเดลด้วยการเอา “พื้นที่ที่มันทายถูกเป๊ะๆ” หารด้วย “พื้นที่ทั้งหมดที่มันเข้าไปยุ่งเกี่ยว” ยิ่งผลหารออกมาใกล้เคียง 1.0 (ทับกันสนิท 100%) แปลว่า AI ตัวนี้คือสไนเปอร์จับวางตัวจริง! แต่ถ้าได้ 0 แปลว่ามันทายไปคนละทิศคนละทางเลยครับ นี่คือคอนเซปต์เบื้องหลังที่เรียบง่ายแต่ทรงพลังสุดๆ ของ IoU

3. 🧠 แก่นวิชา (Core Concepts)

แหล่งข้อมูลระดับโลกได้อธิบายบทบาทและคณิตศาสตร์ของ IoU (หรืออีกชื่อคือ Jaccard Index) ในบริบทของ Object Detection ไว้ดังนี้ครับ:

  • 1. สมการชี้ชะตา (The Formula): IoU คือการคำนวณอัตราส่วนระหว่างพื้นที่ทับซ้อน (Overlap) กับพื้นที่รวมทั้งหมดของ Bounding Box สองกล่อง ได้แก่ กล่องที่ AI ทาย (Predicted Box: $B_{pr}$) และกล่องเฉลยที่คนตีกรอบไว้ (Ground Truth Box: $B_{gt}$)

$$ IoU = \frac{Area_of_Overlap}{Area_of_Union} = \frac{B_{pr} \cap B_{gt}}{B_{pr} \cup B_{gt}} $$

  • 2. เกณฑ์การตัดสิน (The Threshold): เวลาเราได้ค่า IoU มา (ซึ่งมีค่าตั้งแต่ 0 ถึง 1) เราต้องตั้ง “เกณฑ์ (Threshold)” เพื่อตัดสินใจว่า AI ทายถูกหรือไม่ เช่น ถ้าตั้งเกณฑ์ไว้ที่ 0.5 (มาตรฐานคลาสสิกของ PASCAL VOC):
    • True Positive (TP): ถ้า IoU $\ge 0.5$ และทายคลาสถูก ถือว่าสอบผ่าน! จับวัตถุเจอแล้ว
    • False Positive (FP): ถ้าทายคลาสถูก แต่กล่องเบี้ยวจน IoU $< 0.5$ ถือว่าทายผิด (ชี้เป้าพลาด)
  • 3. ฟันเฟืองของ NMS (Non-Maximum Suppression): IoU ไม่ได้มีไว้แค่วัดผลตอนจบนะครับ! ในระหว่างที่โมเดลทำงาน (เช่น YOLO หรือ SSD) มันมักจะตีกรอบซ้ำซ้อนกันหลายสิบกรอบบนวัตถุชิ้นเดียว อัลกอริทึม NMS จะใช้ IoU นี่แหละมาจับผิดว่า “อ้าว! กล่องสองใบนี้มีคลาสเดียวกันแถม IoU สูงปรี๊ด แสดงว่ามันคือของชิ้นเดียวกันนี่หว่า” จากนั้นมันก็จะยุบรวม (Suppress) กล่องที่คะแนนต่ำกว่าทิ้งไป ให้เหลือกล่องเดียวที่สวยที่สุดครับ
  • 4. รากฐานของ mAP: IoU คือจุดเริ่มต้นของการคำนวณตัวชี้วัดระดับประเทศอย่าง Mean Average Precision (mAP) ในการแข่งอย่าง COCO เขาจะคำนวณ mAP โดยกวาดค่า IoU หลายๆ ระดับตั้งแต่ 0.50 ไปจนถึง 0.95 (ขยับทีละ 0.05) เพื่อให้รางวัลกับโมเดลที่ตีกรอบได้ “แนบสนิท” จริงๆ ไม่ใช่แค่พอถูไถครับ
แผนภาพแสดงการคำนวณ Intersection over Union (IoU) ระหว่าง Predicted Box และ Ground Truth Box

4. 💻 ร่ายมนต์โค้ด (Show me the Code)

การเขียนโค้ดเพื่อคำนวณ IoU เป็นโจทย์คลาสสิกที่วิศวกร Vision ทุกคนต้องเคยเขียนครับ พี่มีโค้ดตัวอย่างใน TensorFlow แบบคลีนๆ ที่รองรับการประมวลผลเป็น Batch มาฝาก:

import tensorflow as tf

def calculate_iou(gt_bb, pred_bb):
    """
    ฟังก์ชันคำนวณ IoU แบบ Vectorized
    พิกัดกล่องสมมติให้อยู่ในรูปแบบ [x_min, y_min, x_max, y_max]
    """
    # 📌 1. หาพิกัดของพื้นที่ทับซ้อน (Intersection)
    # ขอบซ้ายและบน ต้องใช้ค่า Max (บีบเข้าหากัน)
    inter_xmin = tf.maximum(gt_bb[:, 0], pred_bb[:, 0])
    inter_ymin = tf.maximum(gt_bb[:, 1], pred_bb[:, 1])
    # ขอบขวาและล่าง ต้องใช้ค่า Min (บีบเข้าหากัน)
    inter_xmax = tf.minimum(gt_bb[:, 2], pred_bb[:, 2])
    inter_ymax = tf.minimum(gt_bb[:, 3], pred_bb[:, 3])

    # 📌 2. คำนวณพื้นที่ทับซ้อน (ต้องเผื่อกรณีกล่องไม่ทับกันเลย ค่าความกว้าง/ยาวจะติดลบ จึงต้อง tf.maximum กับ 0)
    inter_width = tf.maximum(0.0, inter_xmax - inter_xmin)
    inter_height = tf.maximum(0.0, inter_ymax - inter_ymin)
    intersection_area = inter_width * inter_height

    # 📌 3. คำนวณพื้นที่ของแต่ละกล่อง
    gt_area = (gt_bb[:, 2] - gt_bb[:, 0]) * (gt_bb[:, 3] - gt_bb[:, 1])
    pred_area = (pred_bb[:, 2] - pred_bb[:, 0]) * (pred_bb[:, 3] - pred_bb[:, 1])

    # 📌 4. คำนวณพื้นที่รวม (Union) = พื้นที่กล่อง 1 + กล่อง 2 - พื้นที่ทับซ้อน (จะได้ไม่บวกซ้ำ)
    # บวก 1e-10 ป้องกันการหารด้วยศูนย์ (Divide by zero)
    union_area = tf.maximum(gt_area + pred_area - intersection_area, 1e-10)

    # 📌 5. หาอัตราส่วน IoU (Intersection / Union)
    iou = intersection_area / union_area
    return tf.clip_by_value(iou, 0.0, 1.0) # กันเหนียวให้อยู่ในช่วง 0-1 เสมอ

# ตัวอย่างการใช้งาน
# สมมติกล่องเฉลย และกล่องที่ทาย
gt_boxes = tf.constant([[10.0, 10.0, 50.0, 50.0]])
pred_boxes = tf.constant([[20.0, 20.0, 60.0, 60.0]])
print("IoU Score:", calculate_iou(gt_boxes, pred_boxes).numpy())

คอมเมนต์: เทคนิคที่สำคัญมากในโค้ดนี้คือบรรทัด tf.maximum(0.0, ...) ครับ เพราะถ้ากล่องสองใบมันอยู่ห่างกันคนละซีกโลก ขอบเขตที่ตัดกันจะกลายเป็นค่าติดลบ ถ้าเราไม่ดักเป็น 0 ไว้ เอาไปคูณกันมันจะกลายเป็นพื้นที่บวก (ลบคูณลบเป็นบวก) ทำให้ AI ทายว่ามี IoU ซะงั้น! อันนี้บั๊กคลาสสิกที่มือใหม่เจอกันบ่อยเลยครับ

5. 🛡️ เคล็ดลับจากคัมภีร์ลับ (Under the Hood / Pro-Tips)

ถึง IoU จะดูเป็นเครื่องมือครอบจักรวาล แต่หน้างานจริงมีข้อยกเว้นและทริคที่ต้องระวังครับ:

  • เมื่อ IoU ไม่เวิร์กกับ “รอยร้าว” (The Long-Narrow Problem): แหล่งข้อมูลเชิงลึกเตือนไว้ว่า สำหรับโจทย์เฉพาะทางบางอย่าง เช่น การตรวจจับรอยร้าวบนถนน (Crack Detection) ที่วัตถุมีลักษณะเป็นเส้นเรียวยาว การใช้ IoU วัดผลจะห่วยมากครับ! เพราะรอยร้าวใช้พื้นที่พิกเซลน้อยมาก เมื่อนำไปเทียบกับพื้นหลังขนาดใหญ่ พื้นที่ Intersection จะคลาดเคลื่อนได้ง่าย ในกรณีนี้วิศวกรมือโปรมักจะหนีไปใช้ตัวชี้วัดที่ทนทานกว่าอย่าง Hausdorff Distance เข้ามาประเมินความแม่นยำแทนครับ
  • IoU คือ Loss Function ในตัวมันเอง (GIoU / DIoU): ยุคหลังๆ วิศวกรพบว่า การเทรน Regression ด้วย Mean Squared Error (MSE) แล้วมาวัดผลด้วย IoU มันย้อนแย้งกันครับ (Optimize ตัวนึง ไปวัดผลอีกตัวนึง) ยุคนี้เขาเลยเอา IoU มาทำเป็น Loss Function ตรงๆ ไปเลย เช่น Generalized IoU (GIoU) หรือ Distance IoU (DIoU) ที่ช่วยให้ AI รู้ว่าต่อให้กล่องยังไม่ทับซ้อนกัน มันต้องขยับเดินหน้าไปทางทิศไหนถึงจะใกล้ความจริงมากที่สุด โมเดลลู่เข้า (Converge) เร็วขึ้นมหาศาลครับ!
  • ระวัง Trade-off ระหว่าง IoU กับ Recall: ถ้าน้องตั้ง IoU Threshold ไว้สูงลิ่ว เช่น 0.90 (หวังว่ากรอบต้องเนี๊ยบระดับเทพ) สิ่งที่จะเกิดขึ้นคือ AI จะพลาดวัตถุไปเยอะมาก (Recall ตก) เพราะมีกล่องจำนวนมากที่มันทายถูกคลาสและคลุมวัตถุได้ แต่อาจจะตีกรอบเกินไปนิดเดียว ในระบบกล้องวงจรปิด (Surveillance) การตั้ง IoU ที่ 0.5 ก็เพียงพอต่อการใช้งานแล้วครับ

6. 🏁 บทสรุป (To be continued…)

โดยสรุปแล้ว Intersection over Union (IoU) คือ “ไม้บรรทัดมาตรฐาน” ที่ขับเคลื่อนโลกของการทำ Object Detection ทั้งใบครับ ไม่ว่าจะเป็นการวัดว่ากล่องทับซ้อนกับเฉลยแค่ไหน, การกำจัดกล่องขยะผ่าน NMS, หรือการเป็นรากฐานในการคำนวณตัวชี้วัดระดับชาติอย่าง mAP

การเข้าใจคณิตศาสตร์เบื้องหลัง IoU จะทำให้น้องๆ เข้าใจพฤติกรรมการลู่เข้าและการชี้เป้าของ AI ได้อย่างลึกซึ้งยิ่งขึ้นครับ

เมื่อเรารู้วิธีวัดความแม่นยำของกรอบสี่เหลี่ยมแล้ว คำถามสุดท้ายในกระบวนการประเมินผลคือ… แล้วภาพรวมของโมเดลล่ะ? เราจะสรุปคะแนนออกมาเป็นตัวเลขตัวเดียวเพื่อเอาไปพรีเซนต์ให้ลูกค้าดูได้อย่างไร? ในบทความตอนหน้า พี่จะพาน้องๆ ไปลุยกับสุดยอดตัวชี้วัดอย่าง Mean Average Precision (mAP) กันแบบเต็มๆ เตรียมพบกับกราฟ Precision-Recall ที่จะมาปราบเซียนกันได้เลยครับ!


ต้องการที่ปรึกษาและพัฒนาระบบ Automation & Machine Vision ให้กับโรงงานของคุณ? ทีมงาน WP Solution พร้อมให้บริการออกแบบและติดตั้งระบบแบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p