Tạo Ứng Dụng A.I Phát Hiện Người Xâm Nhập (P1)

Tạo Ứng Dụng A.I Phát Hiện Người Xâm Nhập (P1)

Phát hiện người xâm nhập trong các hệ thống an ninh hiện nay đang rất phổ hiến an ninh trong các gia đình, công ty giúp tiết kiệm chi phí an ninh và đảm bảo sự an toàn cho người sử dụng. Vậy để xây dựng được một ứng dụng như vậy chúng ta cần tìm hiểu và tiếp cận ra sao, chúng ta cùng tìm hiểu qua bài viết này nhé.

Trong bài toán phát hiện xâm nhập, người dùng cần phải xác định các cùng cấm, vùng cảnh báo khi phát hiện một hay nhiều người đi vào cùng cảnh báo. Trong hình 1 vùng màu xanh là vùng chung ta cần giám sát và đưa ra cảnh báo khi có đối tượng xâm nhập.

Hình 1: Ví dụ về hệ thông phát hiện xâm nhập

Khi đã xác định được vùng cảnh báo chúng ta cần xác định các đối tượng chuyển động trong khu vực quan tâm để đưa ra cảnh báo. Để xác đinh được đối tượng chuyển động trong ảnh chúng ta thường tiếp cận theo hai cách.

  • Sử dụng các thuật toán xử lý ảnh cơ bản
  • Sử dụng các mô hình học sâu

Trong bài viết này mình sẽ giới thiệu cho mọi người một số phương pháp tiếp cận theo hai cách cơ bản trên.

Phần 1: Sử dụng thuật toán xử lý ảnh cơ bản để phát hiện đối tượng di chuyển trong ảnh.

Một phương pháp đơn giản là Background Subtraction hay thuật toán trừ nên. Thuật toán trừ nên là một kỹ thuật phổ biến được sử dụng rộng rãi để phát hiện các đối tượng chuyển động trong ảnh. Trong phương pháp này chúng ta cần sử dụng video được quay từ một camera cố định.

Hình 2: Thuật toán trừ nền

Để triển khai được thuật toán bạn cần biết một số kiến thức về xử lý ảnh trong thư viên OpenCV một thư viên nổi tiếng về xử lý ảnh. Để làm việc với OpenCV bạn có thể sử dụng C/C++, Python, Java … Trong phạm vi bài chia sẻ này mình sẽ sử dụng ngôn ngữ Python để cài đặt. Trước tiên các bạn cần tìm hiểu một số hàm của thư viện OpenCV.

  • cv2.cvtColor Chuyển đổi không gian màu của ảnh đầu vào
  • cv2.GaussianBlur Làm mờ ảnh sử dụng thuật toán Gaussian
  • cv2.absdiff Tính toán sự khác biệt tuyệt đối giữa 2 ảnh đầu vào
  • cv2.threshold Áp dụng một ngưỡng cố định cho ảnh
  • cv2.dilate Áp dụng thuật toán dãn nở ảnh
# detect.py
import argparse
import datetime
import cv2
import imutils

# Tham số đầu vào
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", help="Nguồn video mặc định 0 là sử dụng webcam", default='0', type=str)
ap.add_argument("-a", "--min-area", type=int, default=300, help="Kích thước nhỏ nhất của đối tượng")
ap.add_argument("-b", "--background", type=str, default=None, help="Ảnh background")
args = vars(ap.parse_args())

# Chọn nguồn video đầu vào
if args['video'] == '0':
    capture = cv2.VideoCapture(0)
else:
    capture = cv2.VideoCapture(args['video'])
# Khởi tạo ảnh background nếu không chuyền vào thì ta lấy ảnh đầu tiên làm background
first_frame = None
if args['background'] is not None:
    first_frame = cv2.imread(args['background'])
    #  Chuyển ảnh đầu vào về ảnh xám
    first_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
    # Làm mờ ảnh
    first_gray = cv2.GaussianBlur(first_gray, (21, 21), 0)

idx = 0
#  Xác định vùng quan sát trên ảnh
top_left, bottom_right = (330, 50), (450, 280)
#  Lặp lần lượt từng frame của video
while True:
    ret, frame = capture.read()
    if frame is None:
        break
    text = "An toan"
    # Resize ảnh về kích thước cố định
    frame = imutils.resize(frame, width=500)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)

    # cv2.imshow("Current frame", frame)

    # Nếu tạo ảnh background nếu không được chuyền vào
    if first_frame is None:
        first_frame = frame
        first_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
        first_gray = cv2.GaussianBlur(first_gray, (21, 21), 0)

    # Tính sự khác biệt giữa ảnh hiện tại và ảnh background
    frameDelta = cv2.absdiff(first_gray, gray)
    # Sử dụng threshold để chuyển ảnh về dụng nhị phân
    thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
    # Thực hiện dãn nở ảnh để làm rõ các cùng vùng màu trắng trong ảnh
    thresh = cv2.dilate(thresh, None, iterations=2)
    # Xác định đường bao cho các đối tượng thu được
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                            cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    # Xác định vùng cần kiểm tra
    cv2.rectangle(frame, top_left, bottom_right, (0, 255, 0), 2)
    for c in cnts:
        # Loại bỏ các đối tượng có kích thước nhỏ
        if cv2.contourArea(c) < args["min_area"]:
            continue
        # Lấy tọa độ của hình chữ nhật bao quanh đối tượng
        (x, y, w, h) = cv2.boundingRect(c)
        # Xác định tâm của đối tượng
        center_x = x + w / 2
        center_y = y + h / 2
        # Kiểm tra đối tượng có nằm trong khu vực quan sát hay không
        logic = top_left[0] < center_x < bottom_right[0] and top_left[1] < center_y < bottom_right[1]
        if logic:
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
            text = "Co xam nhap"
            # Hiện cảnh báo lên hình
            cv2.putText(frame, "Tinh trang: {}".format(text), (10, 20),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
        cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
                    (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
        # show the frame and record if the user presses a key
    cv2.imshow("Camera an ninh", frame)
    # cv2.imshow("Thresh", thresh)
    cv2.imwrite('../images/{}_result.jpg'.format(idx), frame)
    # cv2.imwrite('../images/{}_delta.jpg'.format(idx), frameDelta)
    # cv2.imshow("Frame Delta", frameDelta)
    idx += 1
    keyboard = cv2.waitKey(30)
    if keyboard == 'q' or keyboard == 27:
        break
cv2.destroyAllWindows()

Chạy chương trình

python detect.py -v testvideo.mp4 -b background.jpg -a 300

Kết quả

Đánh giá

Phương pháp tiếp cận sử dụng các thuật toán xử lý ảnh để phát hiện đối tượng di chuyển là một phương pháp đơn giản, dễ dàng triển khai trên các thiết bị như máy tính mini, các thiết bị có cấu hình thấp. Cũng chính vì sự đơn giản của nó nên độ chính xác thường không cao, nhất là các khu vực có điều kiện ánh sáng phức tạp. Phương pháp này chưa phân biệt được người hay vật di chuyển trong video.

Phương pháp phù hợp để triển khai tích hợp trên camera ip, camera hành trình, các khu vực có điệu kiện ánh sáng ổn định, các hệ thống không yêu cầu độ chính xác cao.

Tạm kết

Trong phần này mình đã giới thiệu cho các bạn một phương pháp đơn giản sử dụng các thuật toán xử lý ảnh để phát hiện người xâm nhập. Trong phần 2 mình sẽ giới thiệu các bạn một phương pháp hiện đại và chính xác hơn sử dụng một số kỹ thuật học sâu (AI) để phát hiện người xâm nhập. 

Cảm ơn mọi người đã đọc bài chia sẻ của mình. Nếu có bất kỳ thắc mắc hay ý kiến gì các bạn có thể bình luận bên dưới để mình có thể hỗ trợ.