C++ Opencv 视频处理 行人检测 检测一个区域内是否有行人出现 源码

利用帧差法检测区域内是否有人出现,如果出现行人就报警。

不同的区域位置需要调参,根据摄像头内行人大小调节一下参数

    const double RECT_HW_RATIO = 1.5;    // 人体长宽比阈值
    const double RECT_AREA_RATIO = 0.001;    // 人体占整个图像最小比例阈值
    const double RECT_AREA_RATIO2 = 0.003;    // 人体占整体图像最大比例阈值

 

 

完整代码如下:

#include 
#include 
#include 
#include 
#include 
//#include "DetectPackage.h"
#include 
using namespace std;
using namespace cv;

int main() {
    Mat Image;
    //VideoCapture cap("C:\\Users\\Administrator\\Desktop\\image\\5.mp4");

    Rect cut;
    CvPoint P1, P2;
    P1.x = 1500;
    P1.y = 800;
    P2.x = 600;
    P2.y = 100;     //画一个限制框,只在框内检测

    VideoCapture cap("rtsp://admin:[email protected]/Streaming/Channels/1");//摄像头连接
    if (!cap.isOpened()) {
        cout << "video not exist!" << endl;
        return -1;
    }
    long FRAMECNT = cap.get(CV_CAP_PROP_FRAME_COUNT);

    Mat frame, mask, maskCp;
    vector> cnts;
    Rect maxRect;
    const double RECT_HW_RATIO = 1.5;    // 人体长宽比阈值
    const double RECT_AREA_RATIO = 0.001;    // 人体占整个图像最小比例阈值
    const double RECT_AREA_RATIO2 = 0.003;    // 人体占整体图像最大比例阈值
    Ptr 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) {
        Mat frame;
        cap >> frame;
        rectangle(frame, P1, P2, Scalar(255, 0, 0), 2);
        //cut = Rect(P2.x, P2.y, P1.x, P1.y);
        // frame = frame(cut);


        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 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) {
                cut = Rect(P2.x / 4, P2.y / 4, P1.x / 4, P1.y / 4);
                frame = frame(cut);
                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;
};

 

你可能感兴趣的:(C++源码)