openCV檢測物體是否運動

lightsong發表於2024-11-22

openCV檢測物體是否運動

https://blog.csdn.net/XiBuQiuChong/article/details/135419293

int fmle::capCam() {
    videoCap.open(0);    
    cv::Mat frame1, frame2;
    BOOL ifSuccess = videoCap.read(frame1);
    while (true)
    {
        BOOL ifSuccess = videoCap.read(frame2);
        cv::Mat diff;
        cv::absdiff(frame1, frame2, diff); // 計算兩幀影像的差異
        cv::Mat gray;
        cv::cvtColor(diff, gray, cv::COLOR_BGR2GRAY); // 轉換為灰度影像
        cv::Mat blurred;
        cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0); // 高斯模糊
        cv::Mat thresholded;
        cv::threshold(blurred, thresholded, 20, 255, cv::THRESH_BINARY); // 二值化
        cv::Mat dilated;
        cv::dilate(thresholded, dilated, cv::Mat(), cv::Point(-1, -1), 2); // 膨脹
        std::vector<std::vector<cv::Point>> contours;
        cv::findContours(dilated, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 查詢輪廓
        bool objectMoved = false;
        for (const auto& contour : contours)
        {
            double area = cv::contourArea(contour);
            if (area > 1000) // 設定最小輪廓面積閾值
            {
                objectMoved = true;
                break;
            }
        }
 
        if (objectMoved)
        {
            TRACE("物體移動了\n");
            cv::putText(dilated, "Moving... ", cv::Point(0, 40), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);            
        }
        else
        {
            cv::putText(dilated, "Stopping... ", cv::Point(0, 40), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
            TRACE("物體未移動\n");            
        }        
        frame1 = frame2.clone(); // 更新上一幀影像
        mainDlg->drawMatOfPub(dilated);
        Sleep(40);
    }    
    videoCap.release();    
    
    return 0;
}

監控區域變化

https://blog.csdn.net/youth_shouting/article/details/131967141

import cv2
import numpy as np
import threading

# 初始化pygame庫
pygame.init()
pygame.mixer.init()

# 全域性變數,載入MP3檔案
def load_alarm_sound(file_path):
    try:
        pygame.mixer.music.load(file_path)
    except pygame.error:
        print(f"無法載入音訊檔案:{file_path}")

# 封裝一個播放MP3警報的函式
def play_alarm():
    try:
        # 播放MP3檔案
        pygame.mixer.music.play()
    except pygame.error:
        print("播放警報音訊失敗")

# 呼叫load_alarm_sound函式,載入警報音訊
load_alarm_sound("警報聲.mp3")

should_exit = False
is_alarm = False
prev_frame_image, current_frame_image = None, None

def monitor(data_source):
    global should_exit, is_alarm, prev_frame_image, current_frame_image

    if data_source == "screenshot":
        prev_frame = capture_screen()
    elif data_source == "camera":
        cap = cv2.VideoCapture(0)
        prev_frame = capture_video_frame(cap)

    while not should_exit:
        current_frame = None
        if data_source == "screenshot":
            current_frame = capture_screen()
        elif data_source == "camera":
            current_frame = capture_video_frame(cap)

        if current_frame is not None:
            prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
            current_gray = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
            similarity = ssim(prev_gray, current_gray)

            threshold = 0.95
            if similarity < threshold and not is_alarm:
                print("檢測到較大變化,進行報警!")
                is_alarm = True
                play_alarm()

                # 儲存變化前後的照片
                prev_frame_image = prev_frame.copy()
                current_frame_image = current_frame.copy()

                # 在5秒後重置is_alarm標誌
                threading.Timer(5, reset_alarm_flag).start()
            else:
                print("沒有變化")

        # 更新前一幀影像
        prev_frame = current_frame

        time.sleep(5)  # 等待5秒後再獲取下一幀

    # 釋放資源
    if data_source == "camera":
        cap.release()
    cv2.destroyAllWindows()

def start_recognition():
    global should_exit
    should_exit = False
    print("開始監控")
    th_monitor = threading.Thread(target=monitor, args=("screenshot",))
    th_monitor.daemon = True
    th_monitor.start()

def end_program():
    global should_exit
    should_exit = True
    print("結束程式")
    sys.exit(1)

opencv+python判斷畫面動靜

https://zhuanlan.zhihu.com/p/340754133

 import cv2
 import time
 import numpy as np
 ​
 video_file = "./videos/video.mp4"        
 cap = cv2.VideoCapture(video_file)  #讀取影片檔案,引數設定為0表示從攝像頭獲取影像
 ​
 _, frame1 = cap.read()
 img1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)   #將圖片轉為灰度圖,第一個返回值表示是否轉換成功,第二個返回值就是灰度圖了
 start = time.time()
 ​
 def moving_detect(frame1, frame2):
     img1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
     img2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
     grey_diff = cv2.absdiff(img1, img2)              #計算兩幅圖的畫素差
     change = np.average(grey_diff)
     
     if change > 10:    #當兩幅圖的差異大於給定的值後,認為畫面有物體在動
         cv2.putText(frame2, 'moving', (100, 30), 2, 1,(0,255,0),2,cv2.LINE_AA)
     else:
         cv2.putText(frame2, 'quiet', (100, 30), 2, 1, (255, 0, 0), 2, cv2.LINE_AA)
     cv2.imshow("output", frame2)
 ​
 while True:
     end = time.time()
     if (end - start > 2):                  #每隔2秒拍一幅圖,比較前後兩幅圖的差異
         start = time.time()
         _, frame1 = cap.read()
 ​
     _, frame2 = cap.read()
     moving_detect(frame1, frame2)
     if cv2.waitKey(5) & 0xFF == ord('q'):        #按下q停止執行程式
         break# 最後,關閉所有視窗
 cap.release()
 cv2.destroyAllWindows()

相關文章