OpenCV:09车辆统计项目( 二 )


结果:
识别车辆轮廓:
关键API: cv2.(close,cv2.,cv2.)
我们设置一个阈值,如果某一像素面积大于这个阈值,那么就说明这是
在降噪后的黑白图中得到轮廓的对应(x,y,w,h)坐标,再用cv2.(frame,(int(x),int(y)),(int(x+w),int(y+h)),(0,255,255),2)在原图中画出
# 从去背景例程中,我们可以发现有很多白点(噪声),因此我们需要降噪import cv2import numpy as np# cap = cv2.VideoCapture(0) # 0表示调用摄像头# cap = cv2.VideoCapture('./video.mp4') # 调用视频cap = cv2.VideoCapture('./car.mp4') # 调用视频# 创建一个MOG对象mog = cv2.createBackgroundSubtractorMOG2() # 直接用 不用写参数# 使用opencv获取卷积核kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))# 取阈值,当图形轮廓小于阈值时排除掉(认为它不是车) ——> 只有长宽均大于阈值,才认为是一部车min_w = 90min_h = 90while True:ret,frame = cap.read()if ret == True :# 把原始帧进行灰度化,然后去噪gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)# 去噪(我们可以发现噪声比较均匀,不适合用中值滤波去除,而是用高斯滤波)blur = cv2.GaussianBlur(gray,(7,7),5)#blur = cv2.blur(gray,(3,3))# 去除背景fgmask = mog.apply(blur) # 将前景掩码 "fgmask" 运用到这一帧图像上# 腐蚀做进一步去噪erode = cv2.erode(fgmask,kernel)# 经过腐蚀后车也有些被腐蚀了!再膨胀回来dilate = cv2.dilate(erode,kernel,iterations = 2) # 做两次迭代,膨胀效果更明显(因为我们要求去噪,并不需要和原图一模一样,因此迭代次数可以不一样)# 我们发现有很多内部的小方块 ——> 怎么消除?# 闭运算close = cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)# 识别车辆(对上次形态学操作的结果进行查找轮廓)# 查找轮廓contours,h= cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)# 画出所有检测到的轮廓for contour in contours: # contours是返回的一个列表,列表中放的是一个个ndarray,也就是轮廓的数据# 画最大外界矩形 (要求坐标点都是整数)(x,y,w,h) = cv2.boundingRect(contour) # 返回一个值,这一个值包含了最大外接矩形的x,y,w,h四个变量# 通过外接矩形的宽高大小来过滤掉小的矩形#if w * h < 5000: # 用面积的话误差较大if (w < min_w) and (h < min_h) :continuecv2.rectangle(frame,(int(x),int(y)),(int(x+w),int(y+h)),(0,255,255),2)# 展示#cv2.imshow('video',close) # 显示识别到的前景fgmask(不是写frame!)cv2.imshow('frame',frame) # 显示识别到的前景fgmask(不是写frame!)# 退出key = cv2.waitKey(1) # 每隔1ms接受用户按下的按键# 用户按‘ESC’即可退出if key == 27:break# 最后别忘了释放资源cap.release()cv2.destroyAllWindows()# 结果:动的东西(前景)会变成白色 ;不动的东西(背景)会变成黑色
对车辆进行统计
我们不可能对整幅图进行统计,那样太乱了,也有很多噪声—— 我们应该画一条线,对经过这条线的车辆进行统计
这就有两个难点了:
1.如何画线,在哪画线
2.如何统计
# 我们不可能对整幅图进行统计,那样太乱了,也有很多噪声—— 我们应该画一条线# 这就有两个难点了:1.如何画线,在哪画线2.如何统计import cv2import numpy as np# cap = cv2.VideoCapture(0) # 0表示调用摄像头# cap = cv2.VideoCapture('./video.mp4') # 调用视频cap = cv2.VideoCapture('./car.mp4') # 调用视频# 创建一个MOG对象mog = cv2.createBackgroundSubtractorMOG2() # 直接用 不用写参数# 使用opencv获取卷积核kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))# 取阈值,当图形轮廓小于阈值时排除掉(认为它不是车) ——> 只有长宽均大于阈值,才认为是一部车min_w = 90min_h = 90# 车辆检测线的高度line_high = 450# 车辆检测线的偏移量offset = 6 # 车辆检测线比检测线高offset个像素点或低offset个像素点——都算是被检测到# 设置一个空列表,用于保存汽车外接矩形的中心点cars = []# 当前检测到的车辆数car_num = 0# 计算外接矩形的中心点def center(x,y,w,h):x1 = int(w / 2)y1 = int(h / 2)cx = int(x) + x1cy = int(y) + y1return cx,cywhile True:ret,frame = cap.read()if ret == True :# 把原始帧进行灰度化,然后去噪gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)# 去噪(我们可以发现噪声比较均匀,不适合用中值滤波去除,而是用高斯滤波)blur = cv2.GaussianBlur(gray,(7,7),5)#blur = cv2.blur(gray,(3,3))# 去除背景fgmask = mog.apply(blur) # 将前景掩码 "fgmask" 运用到这一帧图像上# 腐蚀做进一步去噪erode = cv2.erode(fgmask,kernel)# 经过腐蚀后车也有些被腐蚀了!再膨胀回来dilate = cv2.dilate(erode,kernel,iterations = 2) # 做两次迭代,膨胀效果更明显(因为我们要求去噪,并不需要和原图一模一样,因此迭代次数可以不一样)# 我们发现有很多内部的小方块 ——> 怎么消除?# 闭运算close = cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)# 识别车辆(对上次形态学操作的结果进行查找轮廓)# 查找轮廓contours,h= cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)# 画出车辆检测线(在for循环前就可以去计算了,不然每次循环都要画一次线,内存严重消耗)cv2.line(frame,(10,line_high),(1200,line_high),(255,255,0),3) # 参数:画在那、起始点、结束点、颜色# 画出所有检测到的轮廓for contour in contours: # contours是返回的一个列表,列表中放的是一个个ndarray,也就是轮廓的数据# 画最大外界矩形 (要求坐标点都是整数)(x,y,w,h) = cv2.boundingRect(contour) # 返回一个值,这一个值包含了最大外接矩形的x,y,w,h四个变量# 通过外接矩形的宽高大小来过滤掉小的矩形#if w * h