Tracking multiobjects recognized by Haar
I have made a simple code to recognize cars in a highway. The prediction works Ok, however the challenge comes when I would like to track them using the Multitrack method in OpenCV.
The problem is, in each frame the cascade recognizes say, 3 cars. These 3 cars feed the multiobject track, so for every next frame there would be tracked. However the cascade keep recognizing cars that goes into the tracking. Of course a car is the same, so it doesn't need to be recognized again and again.
I am using the video from here - so you can download it and rename it to uk_road.avi.
Here is the image of the result - which you can see multiple boxes are drawn because the multi-object and the cascade are not synchronized.
I am using python 3.6.6 and opencv version 3.4.2
#! /usr/bin/python
import cv2
import numpy as np
import imutils
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 = int(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 = int(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) < 30 and abs(r[1] - ry) < 30:
return False
return True
def detectRegionsOfInterest(frame, cascade):
scaleDown = 2
frameHeight, frameWidth, fdepth = frame.shape
# Resize
frame = cv2.resize(frame, (int(frameWidth/scaleDown), int(frameHeight/scaleDown)))
frameHeight, frameWidth, fdepth = frame.shape
# haar detection.
cars = cascade.detectMultiScale(frame, 2, 1)
newRegions = []
minY = int(frameHeight*0.1)
# iterate regions of interest
for (x,y,w,h) in cars:
roi = [x,y,w,h]
roiImage = frame[y:y+h, x:x+w]
if y > minY:
diffX = diffLeftRight(roiImage)
diffY = round(diffUpDown(roiImage))
if diffX > 200 and diffY > 1200 :
rx,ry,rw,rh = roi
newRegions.append( [rx*scaleDown,ry*scaleDown,rw*scaleDown,rh*scaleDown] )
return newRegions
def detectCars(filename):
trackers = cv2.MultiTracker_create()
rectangles = []
cascade = cv2.CascadeClassifier('cars.xml')
vc = cv2.VideoCapture(filename)
if vc.isOpened():
rval , frame = vc.read()
else:
rval = False
frameCount = 0
while frameCount < 40 :
rval, frame = vc.read()
frame = imutils.resize(frame, width=600)
frameHeight, frameWidth, fdepth = frame ...