Reputation: 169
I'm using a cars cascade to detect all cars in a sample video. The program is currently drawing rectangles around each car it has detected. However, the rectangles keep on changing size from frame to frame. I would like to add some stabilization by keeping the original rectangle if the new rectangle from the next frame overlaps with the previous rectangle. To implement this, I am saving the previous frame (and detecting the cars from the previous frame) and comparing the rectangles of the previous frame with the current frame.
Mat frame;
Mat prevFrame;
while (capture.isOpened()) {
capture.read(frame);
vector<Rect> cars; // center of rectangles where each rectangle contains the detected object
vector<Rect> prevCars; // to store previous tracked rectangles
// Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.
car_cascade.detectMultiScale(frame, cars, 1.1, 2);
if(!prevFrame.empty()) {
car_cascade.detectMultiScale(prevFrame, prevCars, 1.1, 2);
} else {
cout << "EMPTY" << endl; // for testing
}
cout << "current : " << cars.size() << endl; // print out number of cars
cout << "previous: " << prevCars.size() << endl; // print out number of cars
// more code goes here which I haven't written here
frame.copyTo(prevFrame); // set previous frame to current frame
imshow("Video", frame);
char key = waitKey(33);
if (key == 'q')
{
break;
}
}
However, the number of cars detected from the previous frame is not the same as the previous current. E.g.,
EMPTY current : 3 previous: 0 <- 0 because it is empty current : 3 previous: 2 <- previous is 2, but should be 3 since the previous current was 3 current : 3 previous: 2
Upvotes: 2
Views: 451
Reputation: 1695
In order to track and update cars' Rect, here is what I would do (python like code):
def getIndexOfCorrespondingTrackedCar(car) :
for i in range(0, len(tracked_cars)) :
if distance(car.center, tracked_cars[i].center) < THRESHOLD : // you will have to define a threshold according to your case. It has to be smaller than the speed of cars (in px/frame) though.
return(i) // we found the corresponding car in the tracked_cars list
return(-1) // we found no corresponding car, it must be a new car
tracked_cars = [] // list of tracked Rects
cars_current_frame = [] // list of Rects on the current frame
while(camera.open()) :
cars_current_frame = getCarsInFrame(frame) // here you want to use your detectMultiScale function
for ccf in cars_current_frame :
car_idx = getIndexOfCorrespondingTrackedCar(ccf) // get the index of the corresponding car in tracked_cars list
if car_idx is -1 : // No correspondance has been found, this is a new car
tracked_cars.append(ccf)
else :
tracked_cars[car_idx] = ccf // we update the position of the tracked car with its new position
deleteOutdatedCars(tracked_cars) // delete all the tracked cars that haven't been updated for a certain time (it most probably means that the car went off of the frame)
In my example, I only use lists of Rects, but it would be more convenient to use objects here. I recommend you to create a Car class with the following member variables :
I used a similar approach with a hand tracking system and it worked well.
Upvotes: 1