Python-OpenCv实现出入口计数并显示

前言

这是我们数字图像处理课完成的一个实验项目,参考了网上的一些代码,针对我们老师给的需要统计人数的视频进行了一些修改。

源代码下载

一、背景剔除并二值化

高斯模糊:

gray = cv2.GaussianBlur(frame, (31, 31), 0)

作用:视频因为自然震动、光照变化或者摄像头本身等原因产生的噪声,对噪声进行平滑为了避免在运动和跟踪时将其检测出来。

背景剔除

fgbg = cv2.createBackgroundSubtractorKNN()

生成蒙版

fgmask = fgbg.apply(gray)

二值化:

ret,imBin= cv2.threshold(fgmask,200,255,cv2.THRESH_BINARY)

Opening (erode->dilate)

mask = cv2.morphologyEx(imBin, cv2.MORPH_OPEN, kerne3)

开操作(腐蚀->膨胀)消除噪声

mask =  cv2.morphologyEx(mask , cv2.MORPH_CLOSE, kerne3)

Closing (dilate -> erode)

膨胀--最好能使形状比较均匀, 将破碎的区域连接起来

用于形态学处理的核:

调整参数效果会有所改变

kernel = np.ones((3,3),np.uint8)

kerne2 = np.ones((5,5),np.uint8)

kerne3 = np.ones((11,11),np.uint8)

二、目标跟踪

找到边界:

_, contours0, hierarchy = cv2.findContours(mask2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

对每个矩形框:

边框:rect = cv2.boundingRect(cnt)

计算面积:area=cv2.contourArea(cnt)

计算重心:

M=cv2.moments(cnt)

cx=int(M['m10']/M['m00'])

cy=int(M['m01']/M['m00'])

长宽:x, y, w, h = cv2.boundingRect(cnt)

对每个跟踪目标建立MyPerson类:

存储每个矩形框的重心坐标,状态

 

def __init__(self, i, xi, yi, max_age):
        self.i = i
        self.x = xi
        self.y = yi
        self.tracks = []
        self.R = randint(0,255)
        self.G = randint(0,255)
        self.B = randint(0,255)
        self.done = False
        self.state = '0'
        self.age = 0
        self.max_age = max_age
        self.dir = None

将所有识别到的人存储在数组中:

class MultiPerson:
    def __init__(self, persons, xi, yi):
        self.persons = persons
        self.x = xi
        self.y = yi
        self.tracks = []
        self.R = randint(0,255)
        self.G = randint(0,255)
        self.B = randint(0,255)
        self.done = False

三、计数算法

跟踪记录:

先在已有的persons中找到距离最近的,判断其属于同一个人,并更新位置数据

判断方向

画了两条线,一条出口,一条入口,以及limit线(白色):

白线的作用是将已经超过白线范围且记过数的目标人从数组中清除掉,清除内存,加快遍历查找速度

进入:

self.tracks[-1][1] < mid_end and self.tracks[-2][1] >= mid_end

最后一个矩形框的重心坐标小于倒数第二个,且最后一个坐标在入口线的上方,前一个坐标在入口线的下方

出去:

self.tracks[-1][1] > mid_start and self.tracks[-2][1] <= mid_start

最后一个矩形框的重心坐标大于倒数第二个,且最后一个坐标在出口线的下方,前一个坐标在出口线的上方

记录状态:

如果已经记过数则记下状态,之后不再重复计数,提高准确率。

清除人:

已经记过数且超出limit,则将其从内存清除

并排行走改进:

1、对与挨着一起走的人,无法将其完全分开,先记录一个人的宽度,判断其大于一个人的宽度,则用宽度除以每个人的宽度w.

2、修改前面使用的形态学的核,将参数设为长方形或者椭圆形,这样识别单人会更加准确,也可以解决两人并排走的问题。

三、结果分析

 

进入

出去

实际人数

18/19

18

程序计数

18

21

准确率

100%

83.3%

四、存在的问题

漏识别:

对于衣服颜色和背景差不多的人会在某些位置无法识别,影响计数

原因:

图像处理后将其分的太碎导致矩形框面积太小不被识别为跟踪对象,需要进一步调整参数

错误计数

当人数过多时或受周围环境影响,识别的矩形框形状变化频繁,导致重心抖动,过线计数时会多记或者出入记反:

保存输出视频

Cv2.VideoWriter(filename, fourcc, fps, frameSize[, isColor]) 

fourcc = cv2.VideoWriter_fourcc(*'XVID')

第一个参数是要保存的文件的路径

fourcc 指定编码器

fps 要保存的视频的帧率

frameSize 要保存的文件的画面尺寸

isColor 指示是黑白画面还是彩色的画面

编码的含义为:CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec

  • 15
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值