opencv python 三帧差法实现运动目标区域检测与完整代码

三帧差法:连续三帧,12相减,23相减,结果做与运算。

相减公式:opencv python 三帧差法实现运动目标区域检测与完整代码_第1张图片

其中阈值T需要手动调整。

结果得到一个二值图,对二值图做腐蚀,膨胀,在发现轮廓,其中所涉及到得函数有:

cv2.absdiff(img1,img2)#两图相减

cv2.threshold(img,thresh,255,cv2.THRESH_BINARY)#二值化注:此处没有转为1而是255,作用相同

cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))#结构花元素,腐蚀膨胀的kernel

cv2.erode(img,kernel)#腐蚀

cv2.dilate(img,kernel)#膨胀

cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#连通域分析,找轮廓边界

cv2.boundingRect(contour)#轮廓变方框。

import cv2
import numpy as np

def  three_frame_differencing(videopath):
    cap = cv2.VideoCapture(videopath)
    width =int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height =int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    one_frame = np.zeros((height,width),dtype=np.uint8)
    two_frame = np.zeros((height,width),dtype=np.uint8)
    three_frame = np.zeros((height,width),dtype=np.uint8)
    while cap.isOpened():
        ret,frame = cap.read()
        frame_gray =cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        if not ret:
            break
        one_frame,two_frame,three_frame = two_frame,three_frame,frame_gray
        abs1 = cv2.absdiff(one_frame,two_frame)#相减
        _,thresh1 = cv2.threshold(abs1,40,255,cv2.THRESH_BINARY)#二值,大于40的为255,小于0

        abs2 =cv2.absdiff(two_frame,three_frame)
        _,thresh2 =cv2.threshold(abs2,40,255,cv2.THRESH_BINARY)

        binary =cv2.bitwise_and(thresh1,thresh2)#与运算
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
        erode = cv2.erode(binary,kernel)#腐蚀
        dilate =cv2.dilate(erode,kernel)#膨胀
        dilate =cv2.dilate(dilate,kernel)#膨胀

        img,contours,hei = cv2.findContours(dilate.copy(),mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_SIMPLE)#寻找轮廓
        for contour in contours:
            if 100

效果很不好,空洞太大了,准备改用KNN和高斯混合模型试试

涉及代码:

cv2.createBackgroundSubtractorMOG2()
cv2.createBackgroundSubtractorKNN()

高斯混合模型前景提取封装好了直接调用:

fgbg = cv2.createBackgroundSubtractorMOG2()#创建背景剪除

fgmask = fgbg.apply(frame)#获得二值轮廓图

接下了做形态学处理。

  cap = cv2.VideoCapture(r"C:\RecordDownload\NVR-THD_ch3_main_20190423120000_20190423120500.dav")
    kernel =cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
    fgbg =cv2.createBackgroundSubtractorMOG2()
    fourcc = cv2.VideoWriter_fourcc(*"XVID")
    frame1 = np.zeros((640,480))
    out = cv2.VideoWriter("test424.avi",fourcc,10,(640,480))
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
    while cap.isOpened():
        ret,frame =cap.read()
        if not ret:
            break
        cv2.imshow("1",frame)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break

        fgmask =fgbg.apply(frame)
        mask = cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)
        cv2.imshow("2",mask)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break
        _,contours,_ = cv2.findContours(fgmask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        for c in contours:
            if 100

 

你可能感兴趣的:(opencv python 三帧差法实现运动目标区域检测与完整代码)