Chào các bạn, bài đầu tiên trong năm mới 2022 mình xin gửi tới các bạn bài viết Đếm số lượng chỗ trống trong bãi đỗ xe sử dụng OpenCV Python. Đây cũng là bài viết tiếp theo trong series về AI, Machine Learning, Deep Learning, Data Science
Trong bài này chúng ta sẽ áp dụng kỹ thuật xử lý ảnh trong OpenCV và ngôn ngữ lập trình Python để thực hiện nhận diện đối tượng với hình ảnh đưa vào từ camera của bãi đỗ xe.
Ý tưởng bài toán
Ý tưởng khá đơn giản, chúng ta sẽ dùng 1 package của python đó là pickle để lưu lại 1 array chứa các vị trí đỗ xe trong bãi. Sau đó, ta sẽ kiểm tra với hình ảnh được đưa vào từ camera để xác định số lượng chỗ trống trong bãi đỗ xe.
Viết chương trình đếm số lượng chỗ trống trong bãi đỗ xe sử dụng OpenCV Python
Đầu tiên, chúng ta cần tạo danh sách các vị trí trong bãi đậu xe.
Hãy đảm bảo rằng vị trí camera đặt cố định không thay đổi, mình sẽ lấy 1 hình chụp bãi xe từ camera (carParkingImg.png) và sau đó sẽ xác định các vị trí đỗ xe posList và dùng pickle lưu xuống file, ở đây mình đặt tên là CarParkingPos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import cv2 import pickle width, height = 107, 48 try: with open('CarParkingPos', 'rb') as f: posList = pickle.load(f) except: posList = [] def mouseClick(events, x, y, flags, params): if events == cv2.EVENT_LBUTTONDOWN: posList.append((x, y)) if events == cv2.EVENT_RBUTTONDOWN: for i, pos in enumerate(posList): x1, y1 = pos if x1 < x < x1 + width and y1 < y < y1 + height: posList.pop(i) with open('CarParkingPos', 'wb') as f: pickle.dump(posList, f) while True: img = cv2.imread('carParkingImg.png') for pos in posList: cv2.rectangle(img, pos, (pos[0] + width, pos[1] + height), (255, 0, 255), 2) cv2.imshow("Image", img) cv2.setMouseCallback("Image", mouseClick) cv2.waitKey(1) |
Với mỗi 1 chuồng, mình sẽ vẽ 1 khung chữ nhật theo kích thước của chuồng đó. Ta dùng hàm cv2.EVENT_LBUTTONDOWN để tạo mới 1 khung chữ nhật hoặc xóa khung đã có, sau đó cập nhật vào postList.
Sau khi tạo danh sách các vị trí trong bãi đậu xe, chúng ta sẽ viết chương chình chính.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import cv2 import pickle import cvzone import numpy as np cap = cv2.VideoCapture('carParking.mp4') with open('CarParkingPos', 'rb') as f: posList = pickle.load(f) width, height = 107, 48 def checkParkingSpace(imgPro): spaceCounter = 0 for pos in posList: x, y = pos imgCrop = imgPro[y:y + height, x:x + width] count = cv2.countNonZero(imgCrop) if count < 900: color = (0, 255, 0) thickness = 5 spaceCounter += 1 else: color = (0, 0, 255) thickness = 2 cv2.rectangle(img, pos, (pos[0] + width, pos[1] + height), color, thickness) cvzone.putTextRect(img, str(count), (x, y + height - 3), scale=1, thickness=2, offset=0, colorR=color) cvzone.putTextRect(img, f'Free: {spaceCounter}/{len(posList)}', (100, 50), scale=3, thickness=5, offset=20, colorR=(0,200,0)) while True: if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT): cap.set(cv2.CAP_PROP_POS_FRAMES, 0) success, img = cap.read() imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) imgBlur = cv2.GaussianBlur(imgGray, (3, 3), 1) imgThreshold = cv2.adaptiveThreshold(imgBlur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 25, 16) imgMedian = cv2.medianBlur(imgThreshold, 5) kernel = np.ones((3, 3), np.uint8) imgDilate = cv2.dilate(imgMedian, kernel, iterations=1) checkParkingSpace(imgDilate) cv2.imshow("ParkingSpace", img) cv2.waitKey(10) |
Trước tiên, ta load video lên. Ở đây mình dùng 1 file mp4 trích xuất từ camera có tên carParking.mp4
Load posList từ file CarParkingPos.
Sau đó, chúng ta sử lý hình đưa vào, kiểm tra với posList và xuất ra màn hình.
Kết quả cuối cùng chúng ta nhận được:
Leave a Reply