python-opencv实现运动目标检测与视频拼接

opencv版本3.4

# 基本的运动物体检测
# 计算帧之间的差异,或考虑“背景”帧与其他帧之间的差异
import cv2
import numpy as np

##设置为默认摄像头
camera = cv2.VideoCapture('fakeman.avi')  # 读取视频
fourcc = cv2.VideoWriter_fourcc(*'XVID')
fps = camera.get(cv2.CAP_PROP_FPS)
size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))*2, int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))  # 输出视频尺寸,长和宽
print('size', size)
out = cv2.VideoWriter('fakemanout.avi', fourcc, fps, size)  # 输出视频
# getStructuringElement是获取常用的结构元素的形状,MORPH_ELLIPSE是椭圆(包括圆形),后面定义的是大小
es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 4))
kernel = np.ones((5, 5), np.uint8)
background = None

while True:
    ret, frame = camera.read()
    if ret == False:  # 防止下一次循环过程中空图导致错误
        break
    if background is None:  # 初始化背景,后面的图像均以此为背景,即第一张图
        background = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  #灰度化图像
        background = cv2.GaussianBlur(background, (3, 3), 0)  #进行模糊处理 调整高斯核改变轮廓精度
        continue  # 跳出这个循环
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray_frame = cv2.GaussianBlur(gray_frame, (3, 3), 0)
    ##打开系统默认的摄像头获得的视频图像,并将第一帧设置为整个输入的背景
    # 对于每个从该点以后读取的帧都会计算其与背景之间的差异
    diff = cv2.absdiff(background, gray_frame)  # 计算背景帧与当前帧的差值
    retval, diff = cv2.threshold(diff,25, 255, cv2.THRESH_BINARY)  # 25为阈值,255为超过阈值被赋予的值
    diff = cv2.dilate(diff, es, iterations=0)  # 进行图片膨胀,iterations为膨胀次数为0
    # findContours函数计算一幅图像中目标的轮廓,diff.copy()为输入的二值单通道图像
    # 轮廓CV_RETR_EXTERNAL表示只检测外轮廓
    image, cnts, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    for c in cnts:
        if cv2.contourArea(c) < 1500:
            continue
        # c是一个二值图,boundingRect是矩形边框函数,用一个最小的矩形,把找到的形状包起来;
        # x,y是矩形左上点的坐标;w,h是矩阵的宽和高
        (x, y, w, h) = cv2.boundingRect(c)
        # rectangle画出矩形,frame是原图,(x,y)是矩阵的左上点坐标,(x+w,y+h)是矩阵右下点坐标
        # (0,255,0)是画线对应的rgb颜色,2是画线的线宽
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    diff = cv2.merge((diff, diff, diff))
    mix = np.hstack((frame, diff))  # 拼接后的图像
    # cv2.imshow("contours", frame)  #显示轮廓的图像
    # cv2.imshow("dif", diff)
    cv2.imshow('contours+dif', mix)  # 显示拼接后的图像
    # out.write(diff)
    out.write(mix)

    if cv2.waitKey(1000 // 12) & 0xff == ord("q"):
        break

cv2.destroyAllWindows()
out.release()  # 释放
camera.release()

你可能感兴趣的:(计算机视觉)