xxxxhttps://blog.csdn.net/holecloud/article/details/80139297

发布时间 2023-05-21 22:30:40作者: liliczw
#include "stdafx.h"
#include <opencv2\imgproc\imgproc.hpp>
#include <windows.h>
#include <opencv2/opencv.hpp>
#include <cmath>
#include <iostream>
//#include "DetectPackage.h"
#include <cmath>
using namespace std;
using namespace cv;
int main() {
    VideoCapture cap("G://folder/test.mp4");
    if (!cap.isOpened()) {
        cout << "video not exist!" << endl;
        return -1;
    }
    long FRAMECNT = cap.get(CV_CAP_PROP_FRAME_COUNT);
    Mat frame, mask, maskCp;
    vector<vector<Point>> cnts;
    Rect maxRect;
    const double RECT_HW_RATIO = 1.5;    // 人体长宽比阈值
    const double RECT_AREA_RATIO = 0.008;    // 人体占整个图像最小比例阈值
    const double RECT_AREA_RATIO2 = 0.2;    // 人体占整体图像最大比例阈值
    Ptr<BackgroundSubtractorMOG2> bgsubtractor = createBackgroundSubtractorMOG2();
    bgsubtractor->setHistory(20);
    bgsubtractor->setVarThreshold(100);
    bgsubtractor->setDetectShadows(true);
    bool hasPeople = false;        // 是否有人
    int count = 0;    // 帧数
    int hasPeopleFrameCnt = 0; // 每K帧统计到的有人帧数
    int spaceFrames = 0;        // 每隔125帧统计一次
    const int SPACE_FRAME = 125;
 
    while (++count < FRAMECNT - 10) {
        cap >> frame;
        resize(frame, frame, Size(frame.cols / 4, frame.rows / 4));
        // 背景更新
        bgsubtractor->apply(frame, mask, 0.002);
        // 中值滤波
        medianBlur(mask, mask, 3);
        // 阈值分割,去阴影
        threshold(mask, mask, 200, 255, CV_THRESH_BINARY);
        // 找轮廓
        maskCp = mask.clone();
        findContours(maskCp, cnts, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
        vector<Point> maxCnt;
        for (int i = 0; i < cnts.size(); ++i) {
            maxCnt = maxCnt.size() > cnts[i].size() ? maxCnt : cnts[i];
        }
        // 画最大外接矩形
        if (maxCnt.size() > 0) {
            maxRect = boundingRect(maxCnt);
            double rectAreaRatio = (double)maxRect.area() / (frame.cols * frame.rows);
            if ((double)maxRect.height / maxRect.width > RECT_HW_RATIO && rectAreaRatio > RECT_AREA_RATIO &&
                rectAreaRatio < RECT_AREA_RATIO2) {
                rectangle(frame, maxRect.tl(), maxRect.br(), Scalar(0, 255, 0), 2);
                    ++hasPeopleFrameCnt;    
            }
        }
        ++spaceFrames;
        if (spaceFrames >= SPACE_FRAME) {
            if (hasPeopleFrameCnt > SPACE_FRAME / 8) {
                hasPeople = true;
                cout << count << ":有人" << endl;
            }
            else {
                hasPeople = false;
                cout << count << ":无人" << endl;
            }
            hasPeopleFrameCnt = 0;
            spaceFrames = 0;
        }
 
        imshow("frame", frame);
        imshow("mask", mask);
        if (waitKey(10) == 27) {
            break;
        }
    }
    return 0;
};

 

(26条消息) C++ opencv动态行人检测(传统方法)_c++行人检测_holecloud的博客-CSDN博客