利用帧差法检测区域内是否有人出现,如果出现行人就报警。
不同的区域位置需要调参,根据摄像头内行人大小调节一下参数
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;
};