利用图像识别数车和目标追踪

前期规划

准备

素材准备:在天桥处,拍摄多车道视屏。ps为了避免车大灯的干扰,拍摄车尾。

python: opencv,numpy,mat 等

思路

1,准备

自定义车道划分,利用交互操作,画出车道轮廓,利用蒙版对视屏的每一帧进行分割,企图分而治之。ps:缺点,车道划分开之后,如果车进行换道,就不是特别好处理了。

2,数车功能
概括:希望通过,背景提取,把前景(车)提取出来。

因为需要对车进行计数,最简单的方式,比如人数车的时候,会定一个范围,当车辆通过这个范围的时候,人会计数加一。这里的计数我们也采用这种手段。
交互式定义每个车道的数车区范围,大小自拟,位置尽量离摄像头近一些,ps:因为视角原因,在近一点的地方,车辆之间的车头间距在视屏中,会显示的比较大。

对每一帧进行背景提取,获取前景色后,利用蒙版获取各个计数区的前景色。

对前景色的像素点进行统计,画出帧-像素点数量或者百分比的统计图。观察,因为有一定的车头间距,因此,每一辆车经过的时候,前景色的像素点的折线变化是,升高,峰值,降低的过程,简单的说就是统计在一定修正下(局部波动)的峰值或者低谷值

3,跟踪
概括:这一部分简单写过,因为电脑速度有点慢,和算法也有关系,感觉意义不是特别大,在车辆行为跟踪(车头时距,变道行为等),车牌号识别(数车的时候摄像头看不到车牌的)可能有价值

opencv-contrib和opencv都提供了若干算法,算法的参数,帧和被跟踪对象在帧中的范围,即这里划为两个部分:初始化跟踪,跟踪,取消跟踪,ps当距离远,难以实现跟踪的时候,没办法,根据跟踪坐标删除跟踪。

初始化:简单在数车的基础上搭建,ps(懒)。当计数部分加一的时候说明,有车通过计数区,即前后计数区是有车的,之间在峰值处,对车辆位置进行识别,画出大小合适的矩形框,以此初始化,跟踪对象。

跟踪: 跟踪的主要问题是,1算法速度和准确性是否符合你的要求,2,案例视屏中车辆原来越小,算法应有适应性,

取消跟踪;。。。

实现过程(sp 自适应性不好,要自行调节参数)

代码很糙,函数功能的介绍,仅限此处的用法,具体help()就有了。

0,import

import cv2 # opencv,2d图形处理库,
import numpy as np # 科学计算,矩阵等,速度快
import matplotlib.pyplot as plt # 在这里就是为了出个折线图
import gc # 垃圾回收

1,读取视屏

capture = cv2.VideoCapture(r'视屏路径')if __name__ == '__main__':while True:ret , img =  capture.read()if img is None:breakcv2.imshow('window title',img)

cv2.Videocapture() 接受参数,int(摄像头0,1,2,);视屏路径。返回videocapture对象

capture.read() 读取视屏对象,img为每一帧的图像(矩阵形式,size和通道数有关)
cv2.imshow(‘window title’,img):在 window title 的窗口中显示img,注意中文会乱码。

2,视屏的鼠标交互处理

这里先说简单的方法:
为了实现交互,首先读取一帧,选取ROI-兴趣区。

capture = cv2.VideoCapture(r'视屏路径')
ret , frame=  capture.read()
ROI_mem = cv2.selectROI('region of i',img, True,True)

cv2.selectROI()
阻塞函数,但点击enter键后返回,
参数:
窗口名称
要选取兴趣区的底图矩阵
后两个参数你试一下就清楚了
返回值,左上角点的(x,y,w,h)

当然如果你想自定义一个区域,就自己编一个也行
这里比较糙,但简单介绍一下
基本实现的功能是:
画任意一个四边形,可以命名并储存在全局变量point_dict里,
左击确定四边形的锚点,右击撤销锚点

import cv2
import numpy as np
import matplotlib.pyplot as plt
import gc
from copy import deepcopy
global img,pl,point_dict
capture = cv2.VideoCapture(r'Q:\PycharmProjects\untitled1\.idea\图像处理\much.mp4')
ret , img =  capture.read()
pl = []
point_dict = dict()def pl_draw(img,pl):if len(pl)!=0:for i in range(len(pl)-1):cv2.line(img,pl[i],pl[i+1],(255,255,0),1,8)cv2.imshow('image', img)def on_mouse(event, x, y, flags, param):global img, point1, point2,point_dict,plif event == cv2.EVENT_LBUTTONDOWN:         #左键点击point1 = (x,y)if len(pl) ==4:pl.append(pl[0])print('自动闭合'+str(pl))pl_draw(img,pl)name = input('四边形框的名称,如车道-1,或者开始-2')point_dict[name] = plprint('保存成功,第一的框')pl = []else:pl.append(point1)print('保存当前点,pl为:'+str(pl))pl_draw(img.copy(), pl)elif event == cv2.EVENT_MOUSEMOVE:               #按住左键拖曳if len(pl)!=0:pl1 = deepcopy(pl)pl1.append((x, y))pl_draw(img.copy(),pl1 )pl1.pop(-1)elif event == cv2.EVENT_RBUTTONDOWN:         #左键释放if len(pl)!= 0:pl.pop(-1)pl_draw(img.copy(), pl)cv2.namedWindow('image')
cv2.setMouseCallback('image', on_mouse)
cv2.imshow('image', img)
cv2.waitKey(0) == 27

cv2.setMouseCallback(‘image’, on_mouse)
为窗口image 添加鼠标事件的监听,并把事件传递给 on_mouse 函数

3,蒙版功能简单实现

现在综上,已有roi的位置信息。现在要从原图中提取roi,类似于剪切功能。

import cv2
import numpy as np
import matplotlib.pyplot as plt
import gc
from copy import deepcopy
global img,pl,point_dict# 矩形左上端点,和长宽四个参数——>矩形转变4点
def rect_change(p):x,y,w,h = preturn (x,y),(x+w,y),(x+w,y+h),(x,y+h)num = 1
capture = cv2.VideoCapture(r'Q:\PycharmProjects\untitled1\.idea\图像处理\much.mp4')
ret , frame = capture.read()
black = np.full(frame.shape,255,dtype=np.uint8) # 创建一个和frame大小一样的全黑的图像
ret , img =  capture.read()
ROI_mem = cv2.selectROI(frame, False)
black_copy = black.copy()
cv2.fillConvexPoly(black_copy,np.array(rect_change(ROI_mem)),(0,0,0))
while 1:ret, frame = capture.read()img = cv2.add(black_copy,frame)cv2.imshow('mask'


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部