Доброго времени суток. Возникла необходимость считать количество людей заходящих в помещение и выходящих из него. Это я реализовал. Но еще необходимо реализовать подсчёт сколько людей находится еще в помещении.Пример: вошло 15 человек, вышло 9, осталось в помещении 6 человек. если наглядно то надо что-то вроде этого - https://www.youtube.com/watch?v=W-gDfr_G7GA&t=1s
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#include<conio.h> // it may be necessary to change or remove this line if not using Windows
#include <fstream> // file utils
#include <ctime> // timestamp stuff
#include "Blob.h"
#define SHOW_STEPS // un-comment or comment this line to show steps or not
#define FRAME_SCALE 1 // divide frame dimentions by this number
///////////////////////////////////////////////////////////////////////////////////////////////////
int main(void) {
cv::VideoCapture capVideo;
std::ofstream myfile; // log file
cv::Mat imgFrame1;
cv::Mat imgFrame2;
cv::Mat imgFrame1L;
cv::Mat imgFrame2L;
std::vector<Blob> blobs;
cv::Point crossingLine[2];
int ShopCountL = 0;
int ShopCountR = 0;
capVideo.open("input1_2.MOV");
if (capVideo.get(CV_CAP_PROP_FRAME_COUNT) < 2) {
std::cout << "error: video file must have at least two frames";
_getch(); // it may be necessary to change or remove this line if not using Windows
return(0);
}
capVideo.read(imgFrame1L);
capVideo.read(imgFrame2L);
int intVerticalLinePosition = (int)std::round((double)imgFrame1.cols * 0.50);
crossingLine[0].y = 0;
crossingLine[0].x = intVerticalLinePosition;
crossingLine[1].y = imgFrame1.rows - 1;
crossingLine[1].x = intVerticalLinePosition;
char chCheckForEscKey = 0;
bool blnFirstFrame = true;
int frameCount = 2;
imgFrame2Copy = imgFrame2.clone(); // get another copy of frame 2 since we changed the previous frame 2 copy in the processing above
drawBlobInfoOnImage(blobs, imgFrame2Copy);
int blnAtLeastOneBlobCrossedTheLine = checkIfBlobsCrossedTheLine(blobs, intVerticalLinePosition, ShopCountL, ShopCountR, myfile);
if (blnAtLeastOneBlobCrossedTheLine == 1) {
cv::line(imgFrame2Copy, crossingLine[0], crossingLine[1], SCALAR_GREEN, 2);
}
else if (blnAtLeastOneBlobCrossedTheLine == 2) {
cv::line(imgFrame2Copy, crossingLine[0], crossingLine[1], SCALAR_YELLOW, 2);
}
else {
cv::line(imgFrame2Copy, crossingLine[0], crossingLine[1], SCALAR_BLUE, 2);
}
drawShopCountOnImage(ShopCountL, ShopCountR, imgFrame2Copy);
cv::imshow("People_Counting_Cross_Line", imgFrame2Copy);
currentFrameBlobs.clear();
imgFrame1 = imgFrame2.clone(); // move frame 1 up to where frame 2 is
capVideo.read(imgFrame2);
if ((capVideo.get(CV_CAP_PROP_POS_FRAMES) + 1) < capVideo.get(CV_CAP_PROP_FRAME_COUNT)) {
capVideo.read(imgFrame2L);
resize(imgFrame2L, imgFrame2, cv::Size(imgFrame2L.size().width / FRAME_SCALE, imgFrame2L.size().height / FRAME_SCALE));
}
else {
time_t now = time(0);
char* dt = strtok(ctime(&now), "\n");;
std::cout << dt << ",EOF" << std::endl;
return(0); // end?
}
blnFirstFrame = false;
frameCount++;
chCheckForEscKey = cv::waitKey(1);
}
if (chCheckForEscKey != 27) { // if the user did not press esc (i.e. we reached the end of the video)
cv::waitKey(0); // hold the windows open to allow the "end of video" message to show
}
return(0);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
bool checkIfBlobsCrossedTheLine(std::vector<Blob> &blobs, int &intVerticalLinePosition, int &ShopCountL, int &ShopCountR, std::ofstream &myfile) {
bool blnAtLeastOneBlobCrossedTheLine = 0;
for (auto blob : blobs) {
if (blob.blnStillBeingTracked == true && blob.centerPositions.size() >= 2) {
int prevFrameIndex = (int)blob.centerPositions.size() - 2;
int currFrameIndex = (int)blob.centerPositions.size() - 1;
//going left
if (blob.centerPositions[prevFrameIndex].x > intVerticalLinePosition && blob.centerPositions[currFrameIndex].x <= intVerticalLinePosition) {
ShopCountL++;[B][SIZE="3"]вычисление сколько вошло[/SIZE][/B]
[B]вот тут должно быть вычисление сколько осталось еще внутри[/B]
time_t now = time(0);
char* dt = strtok(ctime(&now), "\n");;
std::cout << dt << ",1,0 (Left)" << std::endl;
myfile << dt << ",1,0" << std::endl;
blnAtLeastOneBlobCrossedTheLine = 1;
}
// going right
if (blob.centerPositions[prevFrameIndex].x < intVerticalLinePosition && blob.centerPositions[currFrameIndex].x >= intVerticalLinePosition) {
ShopCountR++;[B]А вот тут сколько вышло[/B]
time_t now = time(0);
char* dt = strtok(ctime(&now), "\n");;
std::cout << dt << ",0,1 (Right)" << std::endl;
myfile << dt << ",0,1" << std::endl;
blnAtLeastOneBlobCrossedTheLine = 2;
}
}
}
return blnAtLeastOneBlobCrossedTheLine;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void drawBlobInfoOnImage(std::vector<Blob> &blobs, cv::Mat &imgFrame2Copy) {
for (unsigned int i = 0; i < blobs.size(); i++) {
if (blobs[i].blnStillBeingTracked == true) {
cv::rectangle(imgFrame2Copy, blobs[i].currentBoundingRect, SCALAR_RED, 2);
int intFontFace = CV_FONT_HERSHEY_SIMPLEX;
double dblFontScale = blobs[i].dblCurrentDiagonalSize / 60.0;
int intFontThickness = (int)std::round(dblFontScale * 1.0);
cv::putText(imgFrame2Copy, std::to_string(i), blobs[i].centerPositions.back(), intFontFace, dblFontScale, SCALAR_GREEN, intFontThickness);
}
}
}