ระบบนับรถผ่านกล้อง (Counting cars through cameras)

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

You may also like...

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *