正文
目录会跟随阅读位置移动。
阅读进度

在交通监控、智能停车场管理等领域,车辆的检测与计数是一项非常重要的任务。借助计算机视觉技术,我们可以实现自动化的车辆检测与计数,提高效率和准确性。本文将详细介绍如何使用 OpenCV 库实现一个简单的车辆检测与计数系统。
整个系统的实现主要分为以下几个步骤:
cv2.findContours 函数查找图像中的轮廓,并筛选出符合条件的车辆轮廓。min_w = 50
min_h = 50
line_high = 325
offset = 12
car_centers = []
carno = 0
drawing = False
current_line = []
polygons = []
min_w 和 min_h:用于筛选车辆轮廓的最小宽度和高度。line_high:检测线的高度。offset:允许车辆中心通过检测线的误差范围。car_centers:用于存储车辆中心坐标的列表。carno:车辆计数器。drawing:用于标记是否正在绘制多边形。current_line:用于存储当前绘制的多边形的顶点。polygons:用于存储所有绘制的多边形。def center(x, y, w, h):
cx = x + w // 2
cy = y + h // 2
return (cx, cy)
def draw_callback(event, x, y, flags, param):
global drawing, current_line
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
current_line = [(x, y)]
elif event == cv2.EVENT_MOUSEMOVE:
if drawing:
current_line.append((x, y))
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
current_line.append((x, y))
if len(current_line) > 2:
polygons.append(current_line.copy())
current_line = []
def is_point_in_any_polygon(point):
if len(polygons) == 0:
return True # 没画区域,全显示
for poly in polygons:
pts = np.array(poly, np.int32)
if cv2.pointPolygonTest(pts, point, False) >= 0:
return True
return False
center 函数:用于计算矩形的中心坐标。draw_callback 函数:鼠标回调函数,用于处理鼠标事件,实现多边形的绘制。is_point_in_any_polygon 函数:用于判断一个点是否在任意一个绘制的多边形内。cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
cv2.namedWindow('dilate', cv2.WINDOW_NORMAL)
cv2.resizeWindow('dilate', 540, 540)
cv2.resizeWindow('frame', 540, 540)
cv2.setMouseCallback('frame', draw_callback)
cap = cv2.VideoCapture("car three.mp4")
bgsubmog = cv2.createBackgroundSubtractorMOG2()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 3)
mask = bgsubmog.apply(blurred)
mask1 = cv2.medianBlur(mask, 5)
eroded = cv2.erode(mask1, kernel)
dilated = cv2.dilate(eroded, kernel, iterations=4)
closed = cv2.morphologyEx(dilated, cv2.MORPH_CLOSE, kernel)
closed = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel)
contours, _ = cv2.findContours(closed, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cv2.line(frame, (10, line_high), (1200, line_high), (255, 255, 0), 2)
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
if w >= min_w and h >= min_h:
center_point = center(x, y, w, h)
if is_point_in_any_polygon(center_point):
car_centers.append(center_point)
cv2.circle(frame, center_point, 5, (0, 255, 0), -1)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
if abs(center_point[1] - line_high) <= offset:
carno += 1
car_centers = []
cv2.putText(frame, f"Car Count: {carno}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
for poly in polygons:
pts = np.array(poly, np.int32)
pts = pts.reshape((-1, 1, 2))
cv2.polylines(frame, [pts], True, (0, 255, 0), 2)
cv2.imshow('frame', frame)
cv2.imshow('dilate', closed)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
通过以上步骤,我们实现了一个简单的车辆检测与计数系统。该系统可以对视频中的车辆进行检测和计数,并允许用户通过鼠标绘制多边形区域,只对该区域内的车辆进行检测和计数。在实际应用中,可以根据需要调整参数和算法,以提高检测的准确性和效率。
交于普通车辆检测代码,此项目添加了上篇所讲的鼠标绘图知识,再次对opencv的学习进行了一次总结。