1 | initial version |
Based on the info and the images that you added (they're not the best ones...), my first approach would be the following:
Additional features/steps may be implemented:
Limitations - this approach won't work properly or won't work at all if:
Some very basic code to start from might be the following (haven't tested it). Of course you will need to tweak parameters and see what works and what does not.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/video.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void main(){
VideoCapture cap(0);
BackgroundSubtractorMOG2 mog;
Mat frame, foreground;
//Define counting windows
Rect in_window = Rect(x1, y1, width1, height1); //fill with coordinates of entry window
Rect out_window = Rect(x2, y2, width2, height2); //fill with coordinates of exit window
//Initialize counters
int numberCars = 0; //total number of cars in a frame
int numberFramesIn = 0; //number of consecutive frames a car is detected in the entry window
int numberFramesOut = 0; //number of consecutive frames a car is detected in the exit window
while (true){
cap >> frame; //capture frame
mog(frame, foreground); //get and store foreground mask (moving objects)
//--For entry window--
int whitePixels = countNonZero(foreground(in_window)); //Count white pixels in window
//If number is higher than a threshold, a car is in the window (here a car is detected
//if more than the 80% of the window is white. You can play around/choose any other criteria)
if (whitePixels > (0.8 * in_window.width * in_window.height)){
numberFramesIn++; //update counter
//If a car is detected over 3 (or whatever) consecutive frames, then it entered the road
if (numberFramesIn > 3){
numberCars++;
}
}
else { //If a car is not detected in the window, reset counter
numberFramesIn = 0;
}
//--For exit window - similar behavior--
whitePixels = countNonZero(foreground(out_window));
if (whitePixels > (0.8 * out_window.width * out_window.height)){
numberFramesOut++;
if (numberFramesOut > 3 && numberCars > 0){ //careful: never less than 0 cars
numberCars--;
}
}
else {
numberFramesOut = 0;
}
cout << "Total number of cars in frame: " << numberCars << endl;
}
}