硬件平台:树莓派4B

工作流程:
读取图像-->灰度-->计算差值->开操作去除噪声(先侵蚀再膨胀)-->检测轮廓-->计算轮廓面积

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@功能描述: 运动识别
@实现方法: 计算两帧之间的差别,查找轮廓
@author: Alex.Duan
"""

import cv2
import numpy as np

# 载入图片
#img1 = cv2.imread("1.png")
#img2 = cv2.imread("2.png")
#cv2.imshow('img1',img1)
#cv2.imshow('img2',img2)

# 从摄像机读入图像
cap = cv2.VideoCapture(0)
cap.set(3,640)
cap.set(4,480) 
ret, img2 = cap.read()
img1 = img2

while True:      
    ret, img2 = cap.read()
    # 转换为灰度图
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

    img1 = img2

    # 计算绝对差,并进行二值化(差值部分为白色)
    diff = cv2.absdiff(gray1, gray2);  
    reval,diff = cv2.threshold(diff, 45, 255, cv2.THRESH_BINARY)

    # 开操作(先侵蚀后膨胀)
    # 侵蚀: 去除干扰点, 5x5矩形核 
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    diff   = cv2.erode(diff,kernel)
    #cv2.imshow('erode',diff)
    # 膨胀: 11x11矩形核(侵蚀与膨胀均对白色部分)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (11, 11))
    diff   = cv2.dilate(diff,kernel)
    cv2.imshow('dilate',diff)

    # 查找轮廓
    image, contours, hierarchy = cv2.findContours(diff, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    
    # 计算轮廓面积
    area = 0
    for i in np.arange(len(contours)):
        area += cv2.contourArea(contours[i])

    # 通过轮廓面积大小来确定事件
    if area > 1000:
        print("Area is %f" %(area))

    # 绘制轮廓
    out = cv2.drawContours(img2, contours,-1, (0,255,0),thickness = 2)
    cv2.imshow('diff',out)
    #cv2.imshow('image',image)

    k = cv2.waitKey(10)
    if k == 27:
        break
# 关闭窗口
cv2.destroyAllWindows()