Day17 偵測移動物體


🟡 先看看程式的效果

今天的程式示範了如何使用 Python 的 OpenCV 函式庫進行實時影像處理,特別是運動檢測。通過從攝影機捕獲影像,程式碼能夠識別並標示出影像中的運動物體,這在安全監控、智能家居及其他自動化應用中具有廣泛的應用潛力。

Today’s program demonstrates how to use the OpenCV library in Python for real-time image processing, particularly motion detection. By capturing images from a camera, the code can identify and mark moving objects in the images, which has broad application potential in security monitoring, smart homes, and other automation applications.


🟡 學習目標

學習如何使用 OpenCV 進行影像捕獲和處理。
理解灰階影像和高斯模糊的概念及其在降噪中的應用。
學會如何計算影像幀之間的差異,並使用二值化技術來識別前景。


🟡 程式碼

請先下載 “偵測移動物體.py”
請按此下載

'''

Python + AI in 21 days
https://jasonworkshop.com/python

Designed by Jason Workshop

[請勿修改以上內容]

---

預備工作:

首先,請確保已安裝 opencv-python, mediapipe 模組
如不確定可直接在 Windows 的 cmd prompt 執行以下指定
pip install opencv-python mediapipe

'''

# 導入OpenCV函式庫
import cv2

# 可以選擇從視訊檔案或攝影機讀取影像
#cap = cv2.VideoCapture('test.avi')  # 從視訊檔案讀取
cap = cv2.VideoCapture(0)            # 從攝影機讀取(0代表預設攝影機)

# 初始化背景幀變數
bg = None

# 主要循環
while True:
    # 讀取影像幀
    # ret: 讀取是否成功的布林值
    # frame: 捕獲的影像幀
    ret, frame = cap.read()
    
    # 將彩色影像轉換為灰階
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 使用高斯模糊降噪
    # (17, 17)是高斯核的大小,數字越大模糊效果越強
    # 0是標準差,讓OpenCV自動計算
    gray = cv2.GaussianBlur(gray, (17, 17), 0)

    # 如果還沒有設定背景,將第一幀設為背景
    if bg is None:
        bg = gray
        continue

    # 計算當前幀與背景的差異
    diff = cv2.absdiff(gray, bg)
    
    # 對差異影像進行二值化處理
    # 閾值30:像素差異大於30視為前景
    # 255:前景像素設為白色(255)
    # cv2.THRESH_BINARY:使用二值化處理
    diff = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY)[1]
    
    # 形態學處理:侵蝕操作
    # 用於消除雜訊(小型白點)
    diff = cv2.erode(diff, None, iterations=2)
    
    # 形態學處理:膨脹操作
    # 用於填補物件中的小洞
    diff = cv2.dilate(diff, None, iterations=2)

    # 尋找輪廓
    # cv2.RETR_EXTERNAL:只檢測最外層輪廓
    # cv2.CHAIN_APPROX_SIMPLE:壓縮水平、垂直和對角線段,只保留端點
    cnts, hierarchy = cv2.findContours(
        diff, 
        cv2.RETR_EXTERNAL, 
        cv2.CHAIN_APPROX_SIMPLE)
    
    # 處理每個找到的輪廓
    for c in cnts:
        # 過濾掉太小的輪廓(面積小於1000像素)
        # 這有助於消除雜訊
        if cv2.contourArea(c) < 1000:
            continue
        
        # 計算輪廓的外接矩形
        # (x,y)是矩形左上角的座標
        # w,h 是矩形的寬度和高度
        (x, y, w, h) = cv2.boundingRect(c)
        # 在原始影像上繪製綠色矩形框
        cv2.rectangle(frame, (x,y), (x+w, y+h), (0,255,0), 2)

    # 顯示處理後的影像
    cv2.imshow("frame", frame)

    # 檢查鍵盤輸入
    # 等待100毫秒,如果按下ESC鍵(鍵值27),則結束程式
    if cv2.waitKey(100) == 27:
        # 關閉所有OpenCV視窗
        cv2.destroyAllWindows()
        break

🟡 小小挑戰一下

大家可以嘗試進行一些修改或改良喔! 例如:
✌️嘗試改變程式對移動物件的敏感度吧!

😁 明天見!

按這裏回到 Python + AI 的 21 天挑戰