动态检测识别opencv

背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤,如果我们有完整的静止的背景帧,那么我们可以通过帧差法来计算像素差从而获得到前景对象。

但是在大多数情况下,我们可能没有这样的图像,所以我们需要从我们拥有的任何图像中提取背景。当运动物体有阴影时,由于阴影也在运动,情况会变的更加复杂,为此引入了背景减除法,通过这一方法我们能够从视频中分离出运动的物体前景,从而达到目标检测的目的。

cv2.BackgroundSubtractorMOG2()用法:

这是一个以混合高斯模型为基础的前景/背景分割算法。它是 P.KadewTraKuPong 和 R.Bowden 在2001年提出的。
它使用 K(K = 3 或 5)个高斯分布混合对背景像素进行建模。使用这些颜色(在整个视频中)存在时间的长短作为混合的权重。背景的颜色一般持续的时间最长,而且更加静止。
在编写代码时,我们需要使用函数:mog = cv2.bgsegm.createBackgroundSubtractorMOG() 创建一个背景对象。
这个函数有些可选参数,比如要进行建模场景的时间长度,高斯混合成分的数量,阈值等。将它们全部设置为默认值,然后在整个视频中我们是需要使用 mask = mog.apply(frame) 就可以得到前景的掩膜了。
移动的物体会被标记为白色,背景会被标记为黑色的。
原文链接:https://blog.youkuaiyun.com/weixin_64443786/article/details/131833812
import cv2
import numpy as np

cv2.namedWindow('video',cv2.WINDOW_NORMAL)
cv2.resizeWindow('video',(640,480))
cap=cv2.VideoCapture(0)#调用自己的摄像头
mog = cv2.createBackgroundSubtractorMOG2()
#kernel1 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))#获取卷积核,相当于np.ones(5,5)
kernel2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))#获取卷积核,相当于np.ones(5,5)

min_w=40#框的大小的参数
min_h=60

line_high=240#线的高度参数

offset=5#在线的周围活动大于line_high才计数

cars=[]
carno=0

def center(x,y,w,h):
    x1=int(w/2)
    y1=int(h/2)
    cx=int(x)+x1
    cy=int(y)+y1
    return cx,cy

#z循环读取视频帧
while True:
        ret,frame=cap.read()#捕捉画面并返回两个值:ret(布尔值,表示是否正确捕捉到图像帧。);frame(图像帧)
        if ret == True:
            gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
            blur=cv2.GaussianBlur(gray,(3,3),5)#(高斯滤波)
            fgmask = mog.apply(blur)#通过apply提取出前景
            #thresh, fgmask = cv2.threshold(fgmask, 150, 255, cv2.THRESH_BINARY)#将图像二值化
            #fgmask1 = cv2.morphologyEx(fgmask, cv2.MORPH_CLOSE, kernel1)#形态学运算,开闭等,后面是卷积核
            fgmask2 = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel2)
            contours,hierarchy = cv2.findContours(fgmask2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#找到经过处理后的图像中可识别的轮廓
            cv2.line(frame,(1,line_high),(630,line_high),(255,0,0),3)
            # print(contours)
            # print('------------------')
            #print(hierarchy)
            for contour in contours:
                x,y,w,h=cv2.boundingRect(contour)#返回框的四个点位
                value1 = (w > min_w) and (h > min_h)  # 判断画出的矩形框是否大于最小值,否则进入下一次循环
                if not value1:
                    continue
                cv2.rectangle(frame,(int(x),int(y)),(int(x+w),int(y+h)),(0,255,255),3)#第一个参数表示在哪个采集处理阶段画框,后面两个是对角坐标
                #cv2.imshow('video',fgmask)

                #将车抽象为一点,即外接矩形的中心点,路过图上线的车才算
                xy1=center(x,y,w,h)
                cars.append(xy1)#做拼接
                cv2.circle(frame,(xy1),5,(0,255,255),-1)#-1代表实心圆
                for (x,y) in cars:
                    if (y>line_high-offset) and (y<line_high+offset):
                        carno+=1
                        cars.remove((x,y))
                        print(carno)
            cv2.imshow('video', frame)
        key=cv2.waitKey(10)
        if key==27:#按ESC退出
            break
cap.release()
cv2.destroyAllWindows()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值