การเขียนโปรแกรมตรวจจับพื้นที่จอดรถว่าง (Parking Space Detection) ด้วย Python และ YOLOv8

21 November 2024     MatumWeb

โครงการนี้ใช้ YOLOv8s ร่วมกับ Python เพื่อระบุพื้นที่จอดรถว่างและนับจำนวนรถที่อยู่ในลานจอด ประกอบด้วยสองสคริปต์หลัก:

    - test1.py: ใช้สำหรับการวาดเส้นรอบพื้นที่จอดรถ

    - test2.py: ใช้สำหรับการตรวจจับรถยนต์และคำนวณจำนวนพื้นที่ว่าง

    

ไลบรารีที่ต้องติดตั้ง

โปรเจกต์นี้ใช้ไลบรารีดังต่อไปนี้:

    - cv2: สำหรับงานด้านการประมวลผลภาพและวิดีโอ

    - numpy: สำหรับการคำนวณและการจัดการข้อมูล

    - cvzone: เครื่องมือสำหรับช่วยการเขียนข้อความและกราฟิกในภาพ

    - pickle: ใช้สำหรับบันทึกและโหลดข้อมูล

    - pandas: ใช้จัดการข้อมูลแบบตาราง

    - ultralytics: สำหรับการใช้งานโมเดล YOLOv8

pip install cv2 numpy cvzone pickle pandas ultralytics



ขั้นตอนการใช้งาน

    1. วาดเส้นรอบพื้นที่จอดรถ

    รันสคริปต์ test1.py เพื่อกำหนดพื้นที่จอดรถที่ต้องการตรวจจับ

    2. นับจำนวนรถและพื้นที่ว่าง

    รันสคริปต์ test2.py เพื่อระบุจำนวนรถยนต์และคำนวณจำนวนที่จอดรถว่าง โดยใช้ข้อมูลจาก test1.py


สคริปต์: test1.py

สคริปต์นี้ช่วยให้คุณสามารถวาดขอบเขตพื้นที่จอดรถในวิดีโอหรือภาพ

import cv2

import numpy as np

import cvzone

import pickle


# เปิดไฟล์วิดีโอ

cap = cv2.VideoCapture('easy1.mp4')


# ตัวแปรเริ่มต้น

drawing = False

area_names = []


try:

    with open("freedomtech", "rb") as f:

        data = pickle.load(f)

        polylines, area_names = data['polylines'], data['area_names']

except:

    polylines = []


points = []

polylines = []


# ฟังก์ชันสำหรับวาดพื้นที่

def draw(event, x, y, flags, param):

    global points, drawing

    if event == cv2.EVENT_LBUTTONDOWN:

        points = [(x, y)]

        drawing = True

    elif event == cv2.EVENT_MOUSEMOVE and drawing:

        points.append((x, y))

    elif event == cv2.EVENT_LBUTTONUP:

        drawing = False

        current_name = input('areaname:-')

        if current_name:

            area_names.append(current_name)

            polylines.append(np.array(points, np.int32))


while True:

    ret, frame = cap.read()

    if not ret:

        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

        continue


    frame = cv2.resize(frame, (1020, 500))


    for i, polyline in enumerate(polylines):

        cv2.polylines(frame, [polyline], True, (0, 0, 255), 2)

        cvzone.putTextRect(frame, f'{area_names[i]}', tuple(polyline[0]), 1, 1)


    cv2.imshow('FRAME', frame)

    cv2.setMouseCallback('FRAME', draw)

    key = cv2.waitKey(100) & 0xFF

    if key == ord('s'):

        with open("freedomtech", "wb") as f:

            pickle.dump({'polylines': polylines, 'area_names': area_names}, f)


cap.release()

cv2.destroyAllWindows()



สคริปต์: test2.py

สคริปต์นี้ใช้โมเดล YOLOv8 เพื่อทำการตรวจจับรถยนต์ในพื้นที่ที่กำหนดไว้

import cv2

import numpy as np

import pickle

import pandas as pd

from ultralytics import YOLO

import cvzone


# โหลดข้อมูลพื้นที่

with open("freedomtech", "rb") as f:

    data = pickle.load(f)

    polylines, area_names = data['polylines'], data['area_names']


# โหลดคลาสจากไฟล์

with open("coco.txt", "r") as f:

    class_list = f.read().split("\n")


# โหลดโมเดล YOLO

model = YOLO('yolov8s.pt')


cap = cv2.VideoCapture('easy1.mp4')

count = 0


while True:

    ret, frame = cap.read()

    if not ret:

        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

        continue


    count += 1

    if count % 3 != 0:

        continue


    frame = cv2.resize(frame, (1020, 500))

    results = model.predict(frame)

    detections = pd.DataFrame(results[0].boxes.data).astype("float")

    detected_cars = []


    for index, row in detections.iterrows():

        x1, y1, x2, y2, _, class_id = row[:6]

        if class_list[int(class_id)] == 'car':

            detected_cars.append([(x1 + x2) // 2, (y1 + y2) // 2])

            cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (255, 255, 255), 2)


    car_counter = []

    for polyline in polylines:

        cv2.polylines(frame, [polyline], True, (0, 255, 0), 2)

        for car in detected_cars:

            if cv2.pointPolygonTest(polyline, tuple(map(int, car)), False) >= 0:

                car_counter.append(car)

                cv2.circle(frame, tuple(map(int, car)), 5, (255, 0, 0), -1)


    car_count = len(car_counter)

    free_spaces = len(polylines) - car_count


    cvzone.putTextRect(frame, f'CAR COUNTER: {car_count}', (50, 60), 2, 2)

    cvzone.putTextRect(frame, f'CAR FREE SPACE: {free_spaces}', (50, 110), 2, 2)

    cv2.imshow('FRAME', frame)


cap.release()

cv2.destroyAllWindows()



ผลลัพธ์

สคริปต์ test1.py ใช้กำหนดพื้นที่จอดรถในวิดีโอ

สคริปต์ test2.py ใช้ตรวจสอบพื้นที่ว่างและแสดงจำนวนรถยนต์ในลานจอด


Github : https://github.com/praphans/parkingspace-detection-python/tree/master