原文: https://pythonspot.com/car-tracking-with-cascades/

使用级联的汽车追踪 - 图1

使用 OpenCV 进行汽车追踪

在本教程中,我们将研究使用 haar 特征的车辆跟踪。 我们有一个经过训练的 haar 级联文件。

该程序将检测感兴趣的区域,将其分类为汽车,并在其周围显示矩形。

级联检测

让我们从基本的级联检测程序开始:

  1. #! /usr/bin/python
  2. import cv2
  3. face_cascade = cv2.CascadeClassifier('cars.xml')
  4. vc = cv2.VideoCapture('road.avi')
  5. if vc.isOpened():
  6. rval , frame = vc.read()
  7. else:
  8. rval = False
  9. while rval:
  10. rval, frame = vc.read()
  11. # car detection.
  12. cars = face_cascade.detectMultiScale(frame, 1.1, 2)
  13. ncars = 0
  14. for (x,y,w,h) in cars:
  15. cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
  16. ncars = ncars + 1
  17. # show result
  18. cv2.imshow("Result",frame)
  19. cv2.waitKey(1);
  20. vc.release()

这样既可以检测屏幕中的汽车,也可以检测到噪声,并且屏幕有时会抖动。 为了避免所有这些情况,我们必须改进我们的汽车跟踪算法。 我们决定提出一个简单的解决方案。

汽车追踪算法

对于每一帧:

  • 检测潜在的感兴趣区域
  • 根据垂直,水平相似度过滤检测到的区域
  • 如果是新区域,请添加到集合中
  • 每 30 帧清除一次收藏

消除误报

均方误差函数用于消除误报。 我们比较图像的垂直和水平方向。 如果差异大或小,就不能成为汽车。

ROI 检测

可能无法在每帧中检测到汽车。 如果检测到新车,则将其添加到集合中。
我们将这个集合保留 30 帧,然后清除它。

  1. #!/usr/bin/python
  2. import cv2
  3. import numpy as np
  4. def diffUpDown(img):
  5. # compare top and bottom size of the image
  6. # 1\. cut image in two
  7. # 2\. flip the top side
  8. # 3\. resize to same size
  9. # 4\. compare difference
  10. height, width, depth = img.shape
  11. half = height/2
  12. top = img[0:half, 0:width]
  13. bottom = img[half:half+half, 0:width]
  14. top = cv2.flip(top,1)
  15. bottom = cv2.resize(bottom, (32, 64))
  16. top = cv2.resize(top, (32, 64))
  17. return ( mse(top,bottom) )
  18. def diffLeftRight(img):
  19. # compare left and right size of the image
  20. # 1\. cut image in two
  21. # 2\. flip the right side
  22. # 3\. resize to same size
  23. # 4\. compare difference
  24. height, width, depth = img.shape
  25. half = width/2
  26. left = img[0:height, 0:half]
  27. right = img[0:height, half:half + half-1]
  28. right = cv2.flip(right,1)
  29. left = cv2.resize(left, (32, 64))
  30. right = cv2.resize(right, (32, 64))
  31. return ( mse(left,right) )
  32. def mse(imageA, imageB):
  33. err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2)
  34. err /= float(imageA.shape[0] * imageA.shape[1])
  35. return err
  36. def isNewRoi(rx,ry,rw,rh,rectangles):
  37. for r in rectangles:
  38. if abs(r[0] - rx) < 40 and abs(r[1] - ry) < 40:
  39. return False
  40. return True
  41. def detectRegionsOfInterest(frame, cascade):
  42. scaleDown = 2
  43. frameHeight, frameWidth, fdepth = frame.shape
  44. # Resize
  45. frame = cv2.resize(frame, (frameWidth/scaleDown, frameHeight/scaleDown))
  46. frameHeight, frameWidth, fdepth = frame.shape
  47. # haar detection.
  48. cars = cascade.detectMultiScale(frame, 1.2, 1)
  49. newRegions = []
  50. minY = int(frameHeight*0.3)
  51. # iterate regions of interest
  52. for (x,y,w,h) in cars:
  53. roi = [x,y,w,h]
  54. roiImage = frame[y:y+h, x:x+w]
  55. carWidth = roiImage.shape[0]
  56. if y > minY:
  57. diffX = diffLeftRight(roiImage)
  58. diffY = round(diffUpDown(roiImage))
  59. if diffX > 1600 and diffX < 3000 and diffY > 12000:
  60. rx,ry,rw,rh = roi
  61. newRegions.append( [rx*scaleDown,ry*scaleDown,rw*scaleDown,rh*scaleDown] )
  62. return newRegions
  63. def detectCars(filename):
  64. rectangles = []
  65. cascade = cv2.CascadeClassifier('cars.xml')
  66. vc = cv2.VideoCapture(filename)
  67. if vc.isOpened():
  68. rval , frame = vc.read()
  69. else:
  70. rval = False
  71. roi = [0,0,0,0]
  72. frameCount = 0
  73. while rval:
  74. rval, frame = vc.read()
  75. frameHeight, frameWidth, fdepth = frame.shape
  76. newRegions = detectRegionsOfInterest(frame, cascade)
  77. for region in newRegions:
  78. if isNewRoi(region[0],region[1],region[2],region[3],rectangles):
  79. rectangles.append(region)
  80. for r in rectangles:
  81. cv2.rectangle(frame,(r[0],r[1]),(r[0]+r[2],r[1]+r[3]),(0,0,255),3)
  82. frameCount = frameCount + 1
  83. if frameCount > 30:
  84. frameCount = 0
  85. rectangles = []
  86. # show result
  87. cv2.imshow("Result",frame)
  88. cv2.waitKey(1);
  89. vc.release()
  90. detectCars('road.avi')

最后说明

级联不是旋转不变的,比例尺和平移的不变。 此外,检测具有 Haar 级联的车辆可能会相当不错,但是使用其他算法(显着点)也会有所收获。

您可能会喜欢:

下载计算机视觉示例和课程