2.车辆检测.txt

UP 返回
对应视频:P81-P86(P84和P83顺序应该交换一下)

1. 环境说明
	按照源代码执行会报错
	!!@@202207251.png_766_107_1@@!!
	需要额外下载opencv-contrib-python模块,且需要和opencv的版本保持一致(opencv-contrib-python作为后者的进阶版,不知道是不是可以只安装前者,以后可以试试)
	
	查看模块版本:pip list
	卸载模块:pip uninstall opencv-contrib-python
	安装指定模块:pip install opencv-contrib-python==4.5.4.58
	
	pip相关命令拓展:
		安装好python后,包管理器pip就已经安装好了,在windows控制台cmd中输入pip就可以查阅到pip一些常用用法:
			安装模块:pip install package
			安装特定版本的第三方包:pip install cchardet==2.1.3	安装2.1.3版本的cchardet(格式:pip install package==version)
			卸载模块:pip uninstall package	建议先将之前的版本的模块卸载后再安装所需版本的模块,如果是模块更新就不需要卸载
			查看当前环境安装的所有包:pip list
			显示所安装包的信息:pip show package
			查看所有可更新的模块:pip list --outdated
			更新某一个模块:pip install --upgrade package
			指定更新源更新模块 :pip install --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple package
			更新所有的模块:pip-review --local --interactive

2. 方法说明
	去背景		此方法与视频中给出的方法有些许差异,应该是版本的问题;视频中的方法在当前opencv中无法运行
		createBackgroundSubtractorMOG2	视频可以根据不同帧像素不变的当做背景,这个方法有一个history=200的参数自定义用来判断的帧数,但是一般使用默认值不给参数就行了
			bgsubmog = cv2.createBackgroundSubtractorMOG2()	#获取背景
			mask = bgsubmog.apply(blur)		#去掉背景获取前景

3. 该检测方法的注意事项
	实际微调时,需要不断调整检测线的参数以使检测数量更精确。后面还会有深度学习的方案来更好的解决统计的问题
	1.如果检测线设计的过粗(线宽和偏移量),就有可能对车辆重复计数,因为中心点可能多次经过线的范围
	2.如果检测线过于靠上或靠下,就会导致对应方向的车辆可能无法被检测到
	3.如果车速过快,这种方法就可能漏检;过慢也可能重复检测

4. 源码:cars.py		测试视频位置:D:\ProjectCodes\VS_Code\testOpenCV\opencv\轮廓

	!!@@202207252.png_1280_745_1@@!!

		import cv2
		import numpy as np
		
		min_w = 90
		min_h = 90
		
		#检测线的高度
		line_high = 550
		
		#线的偏移
		offset = 7
		
		#统计车的数量
		carno =0
		
		#存放有效车辆的数组
		cars = []
		
		#获取车辆矩形的中心点
		def center(x, y, w, h):
		    x1 = int(w/2)
		    y1 = int(h/2)
		    cx = x + x1
		    cy = y + y1
		    return cx, cy
		
		cap = cv2.VideoCapture('video.mp4')
		
		bgsubmog = cv2.createBackgroundSubtractorMOG2()
		
		#形态学kernel
		kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
		
		while True:
		    ret, frame = cap.read()
		    if(ret == True):     
		
		        #灰度
		        cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
		        #去噪(高斯)
		        blur = cv2.GaussianBlur(frame, (3,3), 5)
		        #去背影
		        mask = bgsubmog.apply(blur)
		
		        #腐蚀, 去掉图中小斑块
		        erode = cv2.erode(mask, kernel) 
		
		        #膨胀, 腐蚀后就变小了,不利于识别,所以重新膨胀
		        dilate = cv2.dilate(erode, kernel, iterations = 3)
		
		        #闭操作,去掉物体内部的小块
		        close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
		        close = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel)
		
		        cnts, h = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
		    
		        #画一条检测线
		        cv2.line(frame, (10, line_high), (1200, line_high), (255, 255, 0), 3)
		
		        for (i, c) in enumerate(cnts):
		            (x,y,w,h) = cv2.boundingRect(c)
		
		            #对车辆的宽高进行判断 以验证是否是有效的车辆
		            isValid = ( w >= min_w ) and ( h >= min_h) 
		            if( not isValid):
		                continue
		
		            #到这里都是有效的车 绘制
		            cv2.rectangle(frame, (x, y), (x+w, y+h), (0,0,255), 2)
		            cpoint = center(x, y, w, h) #获取车辆的中心点
		            cars.append(cpoint) 
		            cv2.circle(frame, (cpoint), 5, (0,0,255), -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.putText(frame, "Cars Count:" + str(carno), (500, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (255,0,0), 5)
		        cv2.imshow('video', frame)
		        #cv2.imshow('erode', close)
		    
		    key = cv2.waitKey(1)
		    if(key == 27):
		        break
		
		cap.release()
		cv2.destroyAllWindows()
		
	
DOWN 返回