提交 6a6c53a2 authored 作者: blu's avatar blu

motion detect: new alg

上级 2ea0fac0
......@@ -85,7 +85,7 @@ private:
long long packetTsDelta = 0;
float pps = 0, imgScalor = 1;
int pktLag = 0;
int fps = 18;
int fps = 0;
uint64_t pktCnt = 0;
//
......@@ -550,13 +550,13 @@ private:
}
bool proc = false;
if(pktCnt % (this->fps / detPara.fpsProc + 1) == 0) {
if(this->fps != 0 && pktCnt % (int(this->fps / detPara.fpsProc)) == 0) {
proc = true;
}
if(!proc) {
if(pktCnt %18 == 0)
spdlog::info("{} pps {}, lag {}, skip processing", this->selfId, this->pps, this->pktLag);
if(pktCnt % 60 == 0)
spdlog::info("{} pps {}, fps {}, lag {}, skip processing", this->selfId, this->pps, this->fps, this->pktLag);
}
else {
if(detect) {
......@@ -585,8 +585,10 @@ private:
{
static bool first = true;
static cv::Mat avg;
static double _area = 0;
static int frameProcessed = 0;
vector<vector<cv::Point> > cnts;
cv::Mat origin, gray, thresh;
cv::Mat origin;
avcvhelpers::frame2mat(format, pFrame, origin);
// check region
auto w = origin.size().width;
......@@ -605,10 +607,10 @@ private:
//imgScalor = w * h / (FRAME_SIZE * FRAME_SIZE * 1.0);
// cv::resize(origin, gray, cv::Size(FRAME_SIZE,FRAME_SIZE));
gray = origin.clone();
cv::cvtColor(gray, thresh, cv::COLOR_BGR2GRAY);
float fent = avcvhelpers::getEntropy(thresh);
cv::GaussianBlur(thresh, gray, cv::Size(21, 21), cv::THRESH_BINARY);
cv::Mat gray;
cv::cvtColor(origin, gray, cv::COLOR_BGR2GRAY);
// float fent = avcvhelpers::getEntropy(thresh);
cv::GaussianBlur(gray, gray, cv::Size(21, 21), cv::THRESH_BINARY);
if(first) {
// avg = cv::Mat::zeros(gray.size(), CV_32FC3);
avg.release();
......@@ -619,22 +621,21 @@ private:
}
#ifdef DEBUG
matShow3 = gray.clone();
matShow3 = avg;
matShow2 = origin;
#endif
// packetTm = chrono::system_clock::now();
packetTm = packetTs;
// TODO: AVG
// cv::accumulateWeighted(gray, avg, 0.5);
cv::absdiff(gray, avg, thresh);
avg.release();
avg = gray.clone();
if(!detect || fent < detPara.entropy) {
return;
}
cv::Mat diff;
cv::absdiff(gray, avg, diff);
// if(!detect || fent < detPara.entropy) {
// return;
// }
cv::threshold(thresh, gray, detPara.thre, 255, cv::THRESH_BINARY);
cv::Mat thresh;
cv::threshold(diff, thresh, detPara.thre, 255, cv::THRESH_BINARY);
//cv::dilate(gray, thresh, cv::Mat(), cv::Point(-1,-1), 2);
#ifdef DEBUG
......@@ -643,14 +644,14 @@ private:
cv::findContours(thresh, cnts, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
bool hasEvent = false;
int evtCnt = 0;
static int evtCnt = 0;
int i = 0;
double area = (double)(detPara.area * imgScalor);
if(area < 10) {
area = 10;
}
for(; i < cnts.size(); i++) {
auto _area = cv::contourArea(cnts[i]);
_area = cv::contourArea(cnts[i]);
if(_area < area) {
// nothing
}
......@@ -661,11 +662,14 @@ private:
#ifdef DEBUG
cv::putText(origin, "motion detected", cv::Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0,0,255),2);
#endif
spdlog::info("{} motion detected: idx {}, area: {}", selfId, i, _area);
//spdlog::info("{} motion detected: idx {}, area: {}", selfId, i, _area);
break;
}
} //end for
avg.release();
avg = gray.clone();
frameProcessed++;
spdlog::debug("{} contours {} area {}, thresh {} hasEvent {}", selfId, cnts.size(), hasEvent? cv::contourArea(cnts[i]):0, detPara.area, hasEvent);
// business logic for event
......@@ -674,38 +678,43 @@ private:
long long dura = 0;
if(evtStartTmLast != 0) {
dura = packetTm - evtStartTmLast;
}
switch(evtState) {
case NONE: {
if(hasEvent) {
evtState = PRE;
spdlog::info("{} state: NONE->PRE ({}, {})", selfId, dura, evtCnt);
evtStartTmOrig = packetTm;
}else{
evtStartTmLast = packetTm;
return;
}
break;
}
case PRE: {
switch(evtState) {
case NONE:
case PRE:
if(dura >= detPara.pre) {
if(evtCnt < detPara.fpsProc * dura/2) {
spdlog::info("state: PRE->NONE ({}, {})", dura, evtCnt);
auto thr = frameProcessed/2;
if(evtCnt <= thr) {
if(evtState == PRE) {
spdlog::info("{} state: PRE->NONE ({}, {}, {}, {}, {}, {})", selfId, this->fps, dura, frameProcessed, evtCnt, thr, _area);
evtState = NONE;
evtStartTmOrig = packetTm;
evtStartTmOrig = packetTm - detPara.pre;
}else{
evtState = IN;
spdlog::info("state: NONE->NONE ({}, {}, {}, {}, {}, {})", this->fps, dura, frameProcessed, evtCnt, thr, _area);
}
}else{
if(evtState == PRE) {
json p;
spdlog::info("{} state: PRE->IN ({}, {})", selfId, dura, evtCnt);
evtState = IN;
spdlog::info("{} state: PRE->IN ({}, {}, {}, {}, {}, {})", selfId, this->fps, dura, frameProcessed, evtCnt, thr, _area);
makeEvent(EV_MSG_EVENT_MOTION_START, evtStartTmOrig);
auto tmp = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
packetTsDelta = tmp - packetTm;
spdlog::info("{} packet ts delta: {}", selfId, packetTsDelta);
}else{
evtState = PRE;
spdlog::info("{} state: NONE->PRE ({}, {}, {}, {}, {}, {})", selfId, this->fps, dura, frameProcessed, evtCnt, thr, _area);
evtStartTmOrig = packetTm;
}
}
evtCnt = 0;
frameProcessed = 0;
evtStartTmLast = packetTm;
}
break;
}
case IN: {
if( packetTm - evtStartTmOrig > 60 *detPara.maxDuration ) {
evtStartTmOrig = packetTm;
......@@ -714,30 +723,35 @@ private:
spdlog::warn("{} event video continued over {} minutes, force segmenting and continue", devSn, detPara.maxDuration);
spdlog::debug("{} state: IN->IN ({}, {})",selfId, dura, evtCnt);
evtCnt = 0;
frameProcessed = 0;
evtStartTmLast = packetTm;
}else if(dura >= detPara.post/2){
if(evtCnt < detPara.fpsProc * dura/5){
auto thr = frameProcessed/5;
if(evtCnt <= thr){
evtState = POST;
spdlog::info("{} state: IN->POST ({}, {})", selfId, dura, evtCnt);
spdlog::info("{} state: IN->POST ({}, {}, {}, {}, {}, {})", selfId, this->fps, dura, frameProcessed, evtCnt, thr, _area);
}else{
spdlog::debug("{} state: IN->IN ({}, {})", selfId, dura, evtCnt);
spdlog::info("{} state: IN->IN ({}, {}, {}, {}, {}, {})", selfId, this->fps, dura, frameProcessed, evtCnt, thr, _area);
}
evtCnt = 0;
frameProcessed = 0;
evtStartTmLast = packetTm;
}
break;
}
case POST: {
if(dura >= detPara.post/2){
if(evtCnt < detPara.fpsProc * dura/5){
spdlog::info("state: POST->NONE ({}, {})", dura, evtCnt);
auto thr = frameProcessed/5;
if(evtCnt <= thr){
spdlog::info("{} state: POST->NONE ({}, {}, {}, {}, {}, {})",selfId, this->fps, dura, frameProcessed, evtCnt, thr, _area);
evtState = NONE;
makeEvent(EV_MSG_EVENT_MOTION_END, packetTs);
}else{
spdlog::info("state: POST->IN ({}, {})", dura, evtCnt);
spdlog::info("{} state: POST->IN ({}, {}, {}, {}, {}, {})",selfId, this->fps, dura, frameProcessed, evtCnt, thr, _area);
evtState = IN;
}
evtCnt = 0;
frameProcessed = 0;
evtStartTmLast = packetTm;
}
break;
......@@ -851,28 +865,32 @@ protected:
static int _fpsDetectCnt = 0;
static auto _pts = packet.pts;
if(pAVFormatInput->streams[packet.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){
static auto num = pAVFormatInput->streams[packet.stream_index]->time_base.num;
static auto den = pAVFormatInput->streams[packet.stream_index]->time_base.den;
_fpsDetectCnt++;
if(_fpsDetectCnt < 20){
if(_fpsDetectCnt == 1) {
_pts = packet.pts;
}
}
else{
_pts = packet.pts - _pts;
auto ts = _pts * 1.0* num/den;
this->fps = int(20/ts);
if(this->fps <=5) {
this->fps = 18;
}
spdlog::info("{} calc fps in 20 frame: ts: {}, fps: {}", selfId, ts, this->fps);
_fpsDetectCnt = 0;
_pts = packet.pts;
}
if(pAVFormatInput->streams[packet.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && this->fps == 0){
// static auto num = pAVFormatInput->streams[packet.stream_index]->time_base.num;
// static auto den = pAVFormatInput->streams[packet.stream_index]->time_base.den;
// _fpsDetectCnt++;
// if(_fpsDetectCnt < 20){
// if(_fpsDetectCnt == 1) {
// _pts = packet.pts;
// }
// }
// else{
// _pts = packet.pts - _pts;
// auto ts = _pts * 1.0* num/den;
// this->fps = int(20/ts)+5;
// if(this->fps <=5) {
// this->fps = 18;
// }
// spdlog::debug("{} calc fps in 20 frame: ts: {}, fps: {}", selfId, ts, this->fps);
// _fpsDetectCnt = 0;
// _pts = packet.pts;
// }
auto _fps = av_q2d(pAVFormatInput->streams[packet.stream_index]->r_frame_rate);
this->fps = this->fps > _fps? this->fps:_fps;
}
if(pktCnt % EV_LOG_PACKET_CNT == 0) {
spdlog::info("{} seq: {}, pts: {}, dts: {}, idx: {}", selfId, pktCnt, packet.pts, packet.dts, packet.stream_index);
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论