101.md 5.3 KB
Newer Older
W
wizardforcel 已提交
1
# 使用级联的汽车追踪
W
init  
wizardforcel 已提交
2 3 4 5 6

> 原文: [https://pythonspot.com/car-tracking-with-cascades/](https://pythonspot.com/car-tracking-with-cascades/)

![Car Tracking with OpenCV](img/41e5801abd44884a07aa898717a7e69e.jpg)

W
wizardforcel 已提交
7
使用 OpenCV 进行汽车追踪
W
init  
wizardforcel 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

在本教程中,我们将研究使用 [haar 功能](https://en.wikipedia.org/wiki/Haar-like_features)的车辆跟踪。 我们有一个经过训练的 haar 级联文件。

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

## 级联检测

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

```py
#! /usr/bin/python

import cv2

face_cascade = cv2.CascadeClassifier('cars.xml')
vc = cv2.VideoCapture('road.avi')

if vc.isOpened():
    rval , frame = vc.read()
else:
    rval = False

while rval:
    rval, frame = vc.read()

    # car detection.
    cars = face_cascade.detectMultiScale(frame, 1.1, 2)

    ncars = 0
    for (x,y,w,h) in cars:
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
        ncars = ncars + 1

    # show result
    cv2.imshow("Result",frame)
    cv2.waitKey(1);
    vc.release()

```

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

## 汽车追踪算法

W
wizardforcel 已提交
52
对于每一帧:
W
init  
wizardforcel 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190

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

## 消除误报

[均方误差函数](https://en.wikipedia.org/wiki/Mean_squared_error)用于消除误报。 我们比较图像的垂直和水平方向。 如果差异大或小,就不能成为汽车。

## ROI 检测

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

```py
#!/usr/bin/python

import cv2
import numpy as np

def diffUpDown(img):
    # compare top and bottom size of the image
    # 1\. cut image in two
    # 2\. flip the top side
    # 3\. resize to same size
    # 4\. compare difference
    height, width, depth = img.shape
    half = height/2
    top = img[0:half, 0:width]
    bottom = img[half:half+half, 0:width]
    top = cv2.flip(top,1)
    bottom = cv2.resize(bottom, (32, 64))
    top = cv2.resize(top, (32, 64))
    return ( mse(top,bottom) )

def diffLeftRight(img):
    # compare left and right size of the image
    # 1\. cut image in two
    # 2\. flip the right side
    # 3\. resize to same size
    # 4\. compare difference
    height, width, depth = img.shape
    half = width/2
    left = img[0:height, 0:half]
    right = img[0:height, half:half + half-1]
    right = cv2.flip(right,1)
    left = cv2.resize(left, (32, 64))
    right = cv2.resize(right, (32, 64))
    return ( mse(left,right) )

def mse(imageA, imageB):
    err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2)
    err /= float(imageA.shape[0] * imageA.shape[1])
    return err

def isNewRoi(rx,ry,rw,rh,rectangles):
    for r in rectangles:
        if abs(r[0] - rx) < 40 and abs(r[1] - ry) < 40:
            return False
        return True

def detectRegionsOfInterest(frame, cascade):
    scaleDown = 2
    frameHeight, frameWidth, fdepth = frame.shape
    # Resize
    frame = cv2.resize(frame, (frameWidth/scaleDown, frameHeight/scaleDown))
    frameHeight, frameWidth, fdepth = frame.shape

    # haar detection.
    cars = cascade.detectMultiScale(frame, 1.2, 1)

    newRegions = []
    minY = int(frameHeight*0.3)

    # iterate regions of interest
    for (x,y,w,h) in cars:
        roi = [x,y,w,h]
        roiImage = frame[y:y+h, x:x+w]

        carWidth = roiImage.shape[0]
        if y > minY:
            diffX = diffLeftRight(roiImage)
            diffY = round(diffUpDown(roiImage))
        if diffX > 1600 and diffX < 3000 and diffY > 12000:
            rx,ry,rw,rh = roi
            newRegions.append( [rx*scaleDown,ry*scaleDown,rw*scaleDown,rh*scaleDown] )

    return newRegions

def detectCars(filename):
    rectangles = []
    cascade = cv2.CascadeClassifier('cars.xml')
    vc = cv2.VideoCapture(filename)

    if vc.isOpened():
        rval , frame = vc.read()
    else:
        rval = False

    roi = [0,0,0,0]
    frameCount = 0

    while rval:
    rval, frame = vc.read()
    frameHeight, frameWidth, fdepth = frame.shape

    newRegions = detectRegionsOfInterest(frame, cascade)
    for region in newRegions:
    if isNewRoi(region[0],region[1],region[2],region[3],rectangles):
        rectangles.append(region)

    for r in rectangles:
        cv2.rectangle(frame,(r[0],r[1]),(r[0]+r[2],r[1]+r[3]),(0,0,255),3)

    frameCount = frameCount + 1
    if frameCount > 30:
        frameCount = 0
        rectangles = []

    # show result
    cv2.imshow("Result",frame)
    cv2.waitKey(1);
    vc.release()

detectCars('road.avi')

```

## 最后说明

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

您可能会喜欢:

*   [机器人技术,计算机视觉,语音识别等](https://pythonspot.com/robotics/)

[下载计算机视觉示例+课程](https://pythonspot.com/download-vision-examples/)