1.ที่มาและความสำคัญ
เทคโนโลยีเกี่ยวข้องกับชีวิตประจำวันของมนุษย์อยู่ตลอดเวลา เนื่องจากในการดำรงชีวิตมนุษย์ต้องพบเจอปัญหาต่างๆมากมายในแต่ละวัน ดังนั้นเมื่อเกิดปัญหา มนุษย์ก็คิดหาวิธีแก้ปัญหาทั้งแบบการวิธีการและการสร้างชิ้นงาน ทำให้การใช้ชีวิตมีความสะดวกสบายตามความต้องการของมนุษย์
การพัฒนาเทคโนโลยีในปัจจุบันได้เน้นไปที่ความสะดวกสบายและความปลอดภัยในชีวิตประจำวัน เรื่องของการนับรถเข้า-ออกของมหาวิทยาลัยถือเป็นส่วนหนึ่งที่จะทำให้มนุษย์เราสะดวกขึ้นในด้านการนับจำนวนคน โปรแกรมตรวจนับปริมาณจำนวนของรถบนท้องถนน โดยระบบจะทำงานร่วมกับกล้อง Camera ในการจับภาพแบบ Real Time ควบคู่ไปกับการตรวจนับจำนวน โดยระบบสามารถตรวจนับได้ทั้งขาเข้าและขาออก และแสดงจำนวนดังกล่าวให้เห็นแบบ Real Time โดยข้อมูลดังกล่าวสามารถนำไปใช้สำหรับวางแผนประเมิน และวิเคราะห์การจราจร เพื่อให้เหมาะสมกับช่วงเวลาได้ ซึ่งอาจมีความคลาดเคลื่อนอยู่บ้างเล็กน้อย
2. วัตถุประสงค์
2.1 เพื่อตรวจจับยานพาหนะ
2.2 เพื่อตรวจนับจำนวนยานพาหนะ
2.3 เพื่อเก็บข้อมูลสำหรับวิเคราะห์และวางแผนจัดการจราจรในอนาคต
3. ขอบเขตการทำงาน
• ซอฟต์แวร์วิเคราะห์ภาพในการตรวจจับและนับจำนวนรถที่ผ่าน
• สามารถนับรถขาเข้าและขาออกได้
• ข้อมูลการนับรถจะถูกบันทึกและส่งไปยังศูนย์ควบคุมเพื่อวิเคราะห์และวางแผน
4. ประโยชน์ที่คาดว่าจะได้รับ
- สามารถรวบรวมและเก็บข้อมูลประชากรที่เข้ามาเรียนในมหาวิทยาลัย
- สามารถแยกประเภทรถหรือผู้คนที่เข้ามาในมหาวิทยาลัยได้
- สามารถรับรู้และปรับเปลี่ยนข้อมูลเกี่ยวกับประชากรเพื่อนำไปพัฒนาต่อยอดสิ่งต่างๆได้
5. ความรู้ที่เกี่ยวข้อง
การทำงานร่วมกันของโมดูลเหล่านี้ ได้แก่ cv2
, YOLOv8
, Ultralytics
, และ numpy
จะเน้นไปที่การตรวจจับวัตถุ การประมวลผลภาพ และการคำนวณเชิงตัวเลข ซึ่งจะอธิบายการทำงานของแต่ละโมดูลและความเชื่อมโยงกันดังนี้:
cv2 (OpenCV):
เป็นไลบรารีสำหรับการประมวลผลภาพและวิดีโอ มีฟังก์ชันหลากหลายสำหรับการเปิดไฟล์ภาพ การแปลงภาพ (เช่น การแปลงเป็นระดับสีเทา), การลดเสียงรบกวน, การจับวัตถุที่เคลื่อนไหว, และการแสดงผลภาพ หรือวิดีโอจากกล้องหรือไฟล์
- ตัวอย่างการใช้งาน:
- อ่านและแสดงภาพหรือวิดีโอ
- การแปลงภาพให้เป็นระดับสีเทา
- การวาดรูปร่างหรือข้อความลงบนภาพ
YOLOv8 (You Only Look Once):
YOLOv8 เป็นโมเดลตรวจจับวัตถุที่มีความเร็วและความแม่นยำสูง ถูกพัฒนาโดย Ultralytics มันสามารถตรวจจับวัตถุหลาย ๆ ชนิดในภาพเดียวกันได้ในเวลาจริง (real-time) โดยใช้การตรวจจับผ่านกรอบสี่เหลี่ยมล้อมรอบวัตถุ
- YOLOv8 จะให้ผลลัพธ์เป็นตำแหน่งของวัตถุในภาพพร้อมกับประเภทวัตถุและค่าความมั่นใจ (confidence score)
- YOLO ถูกใช้งานได้ทั้งในรูปแบบที่โหลดโมเดลที่เทรนมาแล้ว (pre-trained) หรือเทรนโมเดลใหม่เพื่อตรวจจับวัตถุเฉพาะ
Ultralytics:
เป็นไลบรารีที่ทำหน้าที่จัดการโมเดล YOLOv8 ซึ่งมาพร้อมกับเครื่องมือในการเทรน ตรวจสอบ และใช้งาน YOLOv8 ได้อย่างง่ายดาย ผู้ใช้สามารถสร้างโมเดลใหม่หรือโหลดโมเดลที่ได้รับการฝึกมาแล้วเพื่อทดสอบกับข้อมูลใหม่ โดย Ultralytics ช่วยให้การพัฒนาเป็นเรื่องง่ายผ่านการจัดการเรื่องการโหลดโมเดล การประมวลผล และการตั้งค่าต่าง ๆ
Numpy (np):
เป็นไลบรารีสำหรับการคำนวณเชิงตัวเลข ใช้ในการจัดการข้อมูลในรูปแบบของอาร์เรย์ (array) หลายมิติ มีการใช้งานร่วมกับ cv2
เพื่อประมวลผลข้อมูลภาพที่อยู่ในรูปแบบอาร์เรย์ ซึ่ง cv2
มักจะคืนค่าภาพในรูปแบบของอาร์เรย์ Numpy ช่วยในการคำนวณค่าสถิติ การแปลงรูปภาพ การหมุน การยืดหด และการบิดเบือนภาพ
– เทคนิคที่ใช้ในการนับรถ:
1. การตรวจจับวัตถุ (Object Detection) ด้วย YOLOv8
• ใช้โมเดล YOLOv8 เพื่อตรวจจับวัตถุในภาพ เช่น รถยนต์และจักรยานยนต์ โดย YOLO จะระบุประเภทของวัตถุที่ตรวจพบและสร้าง bounding box รอบวัตถุเหล่านั้นในแต่ละเฟรมของวิดีโอ
2. การคำนวณจุดศูนย์กลางของวัตถุ (Centroid Calculation)
• โค้ดคำนวณ centroid หรือจุดศูนย์กลางของ bounding box สำหรับแต่ละวัตถุที่ตรวจจับได้ เพื่อใช้ในการติดตามตำแหน่งของวัตถุในเฟรมถัดไป
3. การติดตามวัตถุด้วย Centroid Tracking
• ใช้เทคนิค Centroid Tracking โดยการจับคู่ centroid ของวัตถุในเฟรมปัจจุบันกับเฟรมก่อนหน้า เพื่อติดตามการเคลื่อนที่ของวัตถุแต่ละชิ้น โดยกำหนดระยะห่างสูงสุดที่สามารถจับคู่ centroid ได้ (object_threshold ตั้งค่าไว้ที่ 50) เพื่อลดการนับวัตถุซ้ำ
4. การนับวัตถุผ่านการข้ามเส้นสมมติ (Virtual Line Counting)
• โค้ดตั้งค่าเส้นสมมติในตำแหน่งที่กำหนดสำหรับการนับรถยนต์และจักรยานยนต์ที่เคลื่อนที่เข้าและออก โดยใช้ตำแหน่ง car_line_in_position และ car_line_out_position สำหรับรถยนต์ และ bike_line_in_position และ bike_line_out_position สำหรับจักรยานยนต์
หากวัตถุเคลื่อนที่จากด้านบนของเส้นเข้าแล้วลงมาด้านล่าง ระบบจะนับเป็นการ “เข้า” (เพิ่มค่า car_in หรือ bike_in)
หากวัตถุเคลื่อนที่จากด้านล่างของเส้นออกขึ้นไปด้านบน ระบบจะนับเป็นการ “ออก” (เพิ่มค่า car_out หรือ bike_out)
5. การอัปเดตข้อมูลการติดตามวัตถุ (Object Tracker Update)
• ใช้ตัวแปร car_trackers และ bike_trackers เพื่อเก็บข้อมูล centroid ของวัตถุแต่ละชิ้น โดยอัปเดตตำแหน่งของวัตถุในแต่ละเฟรม และใช้ ID เพื่อติดตามวัตถุอย่างต่อเนื่อง
สรุปเทคนิคที่ใช้
• การตรวจจับวัตถุด้วย YOLOv8
• การคำนวณและติดตาม centroid ของวัตถุ
• การจับคู่ centroid ด้วยระยะห่างเพื่อระบุการเคลื่อนที่
• การนับผ่านเส้นสมมติ (Virtual Line Counting)
– เมื่อ centroid ระบุวัตถุที่เคลื่อนที่แล้วเข้าไปที่เส้นสมมติจากนั้นจะทำการนับรถที่ข้ามเส้น
6. การดำเนินงาน
ผังงานการทำงานของระบบ
Code
import cv2
from ultralytics import YOLO
import numpy as np
model = YOLO('yolov8n.pt')
cap = cv2.VideoCapture("./mp4/car4.mp4")
# ตัวแปรสำหรับนับรถยนต์และจักรยานยนต์
car_in = 0
car_out = 0
bike_in = 0
bike_out = 0
# เส้นนับเข้าและออก
car_line_in_position = 490 # เส้นนับเข้ารถยนต์
car_line_out_position = 470 # เส้นนับออกรถยนต์
bike_line_in_position = 490 # เส้นนับเข้าจักรยานยนต์
bike_line_out_position = 470 # เส้นนับออกจักรยานยนต์
# ตัวแปรติดตามวัตถุ
car_trackers = {}
bike_trackers = {}
next_car_id = 0
next_bike_id = 0
object_threshold = 50 # ระยะทางสูงสุดในการจับคู่ centroid
while True:
ret, frame = cap.read()
if not ret:
break
results = model(frame)
car_centroids = []
bike_centroids = []
for result in results:
for box in result.boxes:
cls = int(box.cls[0])
label = model.names[cls]
if label == "car":
x1, y1, x2, y2 = box.xyxy[0]
x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
centroid = np.array([(x1 + x2) / 2, (y1 + y2) / 2])
car_centroids.append(centroid)
elif label == "motorcycle":
x1, y1, x2, y2 = box.xyxy[0]
x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
centroid = np.array([(x1 + x2) / 2, (y1 + y2) / 2])
bike_centroids.append(centroid)
# อัปเดตตัวติดตามรถยนต์
updated_car_trackers = {}
for centroid in car_centroids:
min_distance = float("inf")
best_match_id = None
for object_id, object_centroid in car_trackers.items():
distance = np.linalg.norm(object_centroid - centroid)
if distance < min_distance and distance < object_threshold:
min_distance = distance
best_match_id = object_id
if best_match_id is None:
updated_car_trackers[next_car_id] = centroid
next_car_id += 1
else:
updated_car_trackers[best_match_id] = centroid
# อัปเดตตัวติดตามจักรยานยนต์
updated_bike_trackers = {}
for centroid in bike_centroids:
min_distance = float("inf")
best_match_id = None
for object_id, object_centroid in bike_trackers.items():
distance = np.linalg.norm(object_centroid - centroid)
if distance < min_distance and distance < object_threshold:
min_distance = distance
best_match_id = object_id
if best_match_id is None:
updated_bike_trackers[next_bike_id] = centroid
next_bike_id += 1
else:
updated_bike_trackers[best_match_id] = centroid
# ตรวจสอบการข้ามเส้นของรถยนต์
for object_id, centroid in updated_car_trackers.items():
prev_centroid = car_trackers.get(object_id)
if prev_centroid is not None:
if prev_centroid[1] < car_line_in_position car_line_out_position >= centroid[1]:
car_out += 1
cv2.circle(frame, tuple(centroid.astype(int)), 4, (0, 255, 0), -1)
cv2.putText(frame, f"Car ID: {object_id}", (centroid[0].astype(int) - 10, centroid[1].astype(int) - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# ตรวจสอบการข้ามเส้นของจักรยานยนต์
for object_id, centroid in updated_bike_trackers.items():
prev_centroid = bike_trackers.get(object_id)
if prev_centroid is not None:
if prev_centroid[1] < bike_line_in_position bike_line_out_position >= centroid[1]:
bike_out += 1
cv2.circle(frame, tuple(centroid.astype(int)), 4, (255, 0, 0), -1)
cv2.putText(frame, f"Bike ID: {object_id}", (centroid[0].astype(int) - 10, centroid[1].astype(int) - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
car_trackers = updated_car_trackers
bike_trackers = updated_bike_trackers
# วาดเส้นแบ่งรถยนต์และจักรยานยนต์
cv2.line(frame, (0, car_line_in_position), (frame.shape[1], car_line_in_position), (0, 255, 255), 2)
cv2.line(frame, (0, car_line_out_position), (frame.shape[1], car_line_out_position), (255, 255, 0), 2)
cv2.line(frame, (0, bike_line_in_position), (frame.shape[1], bike_line_in_position), (0, 0, 255), 2)
cv2.line(frame, (0, bike_line_out_position), (frame.shape[1], bike_line_out_position), (255, 0, 255), 2)
# แสดงผลนับรถยนต์และจักรยานยนต์
cv2.putText(frame, f"Cars In: {car_in}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.putText(frame, f"Cars Out: {car_out}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.putText(frame, f"Bikes In: {bike_in}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
cv2.putText(frame, f"Bikes Out: {bike_out}", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
cv2.imshow("Frame", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
7. วิธีการใช้งานโปรแกรม
การนับรถเข้า-ออกสามารถทำได้โดยใช้เทคโนโลยีการตรวจจับภาพ เช่น YOLO (You Only Look Once) หรือ OpenCV เพื่อระบุและนับจำนวนรถที่ผ่านเข้าหรือออกจากพื้นที่ที่กำหนด โดยมีขั้นตอนหลัก ๆ ดังนี้:
ขั้นตอนที่ 1: นำเข้าวิดีโอจากกล้องที่ใช้หรือไฟล์
: คำสั่งนี้ใช้เปิดไฟล์วิดีโอชื่อ “car4.mp4” ที่อยู่ในโฟลเดอร์ mp4 โดยเก็บวิดีโอที่เปิดไว้ในตัวแปร cap
เพื่อใช้ในกระบวนการประมวลผลวิดีโอต่อไป
ขั้นตอนที่ 2: ปรับแต่งการนับเส้นการเข้า-ออก (กรณีที่เส้นการนับรถไม่เหมาะกับวิดีโอ)
: คุณสามารถใช้วิธีการนับจำนวนรถด้วยการสร้างเส้นสมมติบนจอ และตรวจสอบว่ารถผ่านเส้นเข้าไปในทิศทางใด
– การปรับเปลี่ยนเส้นสมมติให้เป็นส่วนนึงที่จะทำให้มีผลต่อการตรวจจับยานพาหนะในมุมกล้อง โดยเฉพาะอย่างยิ่งหากมุมกล้องหรือทิศทางการเคลื่อนที่ของยานพาหนะไม่อยู่ในแนวตั้งตรงกับเส้นเหล่านี้ อาจทำให้การนับไม่แม่นยำ
ขั้นตอนที่ 3: กดเริ่มโปรแกรม
: เมื่อเสร็จสิ้นทุกอย่าง สามารถนำวิดีโอที่เราต้องการและเปิด โปรแกรม Visual Studio Code ได้เลยเพื่อเริ่มการทำงาน
ขั้นตอนที่ 4: การกดปุ่มเพื่อออกจากการทำงานของโปรแกรม
: คำสั่งนี้ทำหน้าที่แสดงผลเฟรมภาพ และจะหยุดการทำงานเมื่อกดปุ่ม ‘q’
– เราสามารถเปลี่ยนปุ่มคำสั่งปิดได้ตามที่ต้องการ ในส่วนนี้ ord(‘ ‘)
8. การทดลอง
ทดลองนำระบบนับรถเข้า-ออก ให้ทำงานโดยรับเข้าภาพและวิดีโอที่ถ่ายจากมุมด้านบน
และเปิด โปรแกรม Visual Studio Code ได้เลยเพื่อเริ่มการทำงาน
9. ผลการทดลอง
สรุปผล จากการทดลองผลปรากฎว่าการใช้งานโปรแกรมนั้นมีประสิทธิภาพ โปรแกรมสามารถจับภาพวิดีโอรถเข้า-ออกได้เป็นอย่างดีแต่ทั้งนี้ก็ขึ้นอยู่กับวิดีโอที่เลือกใช้ ปัจจัยต่างๆ เช่น มุมที่ถ่ายอาจไม่เหมาะกับการ ตั้งเส้นเข้า-ออกรถ, วิดีโอในกลางคืนถ้ามืดเกินไปก็อาจทำให้จับภาพรถไม่ได้ แต่โดยรวมแล้วมุมกล้องที่ดีก็สามารถทำให้โปรแกรมทำงานได้อย่างมีประสิทธิภาพ
ข้อเสนอแนะ — ควรจัดหามุมกล้องที่ดีเพื่อประสิทธิภาพที่สูงขึ้นอย่างมาก —
10. ข้อมูลอ้างอิง
ใช้ใน Python เป็นไลบรารีโอเพนซอร์สที่ใช้สำหรับงานด้านการประมวลผลภาพและการมองเห็นของคอมพิวเตอร์ (Computer Vision) มีเครื่องมือที่หลากหลายสำหรับการจัดการกับภาพและวิดีโอ รวมถึงการตรวจจับวัตถุ การตรวจสอบใบหน้า การตรวจจับการเคลื่อนไหว และอื่น ๆ OpenCV ถูกใช้อย่างแพร่หลายในงานวิจัย, วิศวกรรม, AI, และงานด้านการเรียนรู้ของเครื่อง (Machine Learning) เนื่องจากรองรับการทำงานที่ซับซ้อนและสามารถทำงานได้อย่างมีประสิทธิภาพสูง https://phyblas.hinaboshi.com/oshi01
NumPy เป็นไลบรารีที่ใช้สำหรับการคำนวณเชิงตัวเลขและวิทยาศาสตร์ข้อมูล ซึ่งมาพร้อมกับเครื่องมือที่มีประสิทธิภาพสำหรับการทำงานกับ อาเรย์ (arrays) และ เมทริกซ์ (matrices) รวมถึงฟังก์ชันทางคณิตศาสตร์ที่ใช้ในการจัดการและวิเคราะห์ข้อมูลได้อย่างรวดเร็ว https://www.borntodev.com/2020/04/16/%E0%B8%9E%E0%B8%B7%E0%B9%89%E0%B8%99%E0%B8%90%E0%B8%B2%E0%B8%99%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B9%83%E0%B8%8A%E0%B9%89-numpy-%E0%B9%83%E0%B8%99-python-3/
โมดูล Ultralytics เป็นไลบรารีที่พัฒนาเพื่อใช้งานโมเดล YOLO (You Only Look Once) ซึ่งเป็นหนึ่งในโมเดลยอดนิยมสำหรับการตรวจจับวัตถุในภาพและวิดีโอ โมเดล YOLO มีชื่อเสียงในเรื่องของความเร็วและความแม่นยำ โดยสามารถทำงานแบบเรียลไทม์ได้เป็นอย่างดี https://github.com/ultralytics/ultralytics
โมดูล Ultralytics เป็นไลบรารีที่พัฒนาเพื่อใช้งานโมเดล YOLO (You Only Look Once) ซึ่งเป็นหนึ่งในโมเดลยอดนิยมสำหรับการตรวจจับวัตถุในภาพและวิดีโอ โมเดล YOLO มีชื่อเสียงในเรื่องของความเร็วและความแม่นยำ โดยสามารถทำงานแบบเรียลไทม์ได้เป็นอย่างดี https://github.com/ultralytics/ultralytics
วิดีโอการทำงานของระบบตรวจนับรถเข้า-ออก
สมาชิกในกลุ่ม
นายสุระภี เกษรินทร์ วต. 081
นายตะวัน ระเหม วต. 064
นายภานุวัฒน์ ใยดี วต. 075
นายฟารุก เส็นส๊ะ วต. 074