提交 d67a3d07 authored 作者: blu's avatar blu

motion detect: merge

...@@ -85,6 +85,8 @@ private: ...@@ -85,6 +85,8 @@ private:
long long packetTsDelta = 0; long long packetTsDelta = 0;
float pps = 0, imgScalor = 1; float pps = 0, imgScalor = 1;
int pktLag = 0; int pktLag = 0;
int fps = 0;
uint64_t pktCnt = 0;
// //
int handleCloudMsg(vector<vector<uint8_t> > v) int handleCloudMsg(vector<vector<uint8_t> > v)
...@@ -520,6 +522,9 @@ private: ...@@ -520,6 +522,9 @@ private:
return response; return response;
} }
static long long called = 0;
static int factor = 0;
while (response >= 0) { while (response >= 0) {
response = avcodec_receive_frame(pCodecContext, pFrame); response = avcodec_receive_frame(pCodecContext, pFrame);
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) { if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
...@@ -540,46 +545,25 @@ private: ...@@ -540,46 +545,25 @@ private:
pFrame->key_frame, pFrame->key_frame,
pFrame->coded_picture_number pFrame->coded_picture_number
); );
break;
static long long called = 0;
static int factor = 0;
called++;
bool proc = true;
if(this->pps != 0 && factor == 0) {
// lock the value
factor = int(int(this->pps) / this->detPara.fpsProc); // regulator to 0 if it was set inresonably high
if(factor > 8) {
factor = 8;
} }
} }
if(factor != 0 ) { bool proc = false;
if(called % factor == 0) { if(this->fps != 0 && pktCnt % (int(this->fps / detPara.fpsProc)) == 0) {
proc = true; proc = true;
//factor = 0; // reset it open to change
}
else {
proc = false;
}
} }
if(!proc) { if(!proc) {
if(this->pps != 0 && (called %180) == 0) { if(pktCnt % 60 == 0)
spdlog::info("{} pps {}, fpsFactor {}, called {}, lag {}, skip processing", this->selfId, this->pps, factor, called, this->pktLag); spdlog::info("{} pps {}, fps {}, lag {}, skip processing", this->selfId, this->pps, this->fps, this->pktLag);
}
// detectMotion(pCodecContext->pix_fmt, pFrame, false);
} }
else { else {
if((called % (180*4)) == 0) { if(detect) {
spdlog::info("{} pps {}, fpsFactor {}, called {}, lag {}", this->selfId, this->pps, factor, called, this->pktLag);
}
detectMotion(pCodecContext->pix_fmt, pFrame, detect); detectMotion(pCodecContext->pix_fmt, pFrame, detect);
factor = 0; // refresh to latest value
}
break;
} }
} }
return 0; return 0;
} }
...@@ -601,8 +585,10 @@ private: ...@@ -601,8 +585,10 @@ private:
{ {
static bool first = true; static bool first = true;
static cv::Mat avg; static cv::Mat avg;
static double _area = 0;
static int frameProcessed = 0;
vector<vector<cv::Point> > cnts; vector<vector<cv::Point> > cnts;
cv::Mat origin, gray, thresh; cv::Mat origin;
avcvhelpers::frame2mat(format, pFrame, origin); avcvhelpers::frame2mat(format, pFrame, origin);
// check region // check region
auto w = origin.size().width; auto w = origin.size().width;
...@@ -621,10 +607,10 @@ private: ...@@ -621,10 +607,10 @@ private:
//imgScalor = w * h / (FRAME_SIZE * FRAME_SIZE * 1.0); //imgScalor = w * h / (FRAME_SIZE * FRAME_SIZE * 1.0);
// cv::resize(origin, gray, cv::Size(FRAME_SIZE,FRAME_SIZE)); // cv::resize(origin, gray, cv::Size(FRAME_SIZE,FRAME_SIZE));
gray = origin.clone(); cv::Mat gray;
cv::cvtColor(gray, thresh, cv::COLOR_BGR2GRAY); cv::cvtColor(origin, gray, cv::COLOR_BGR2GRAY);
float fent = avcvhelpers::getEntropy(thresh); // float fent = avcvhelpers::getEntropy(thresh);
cv::GaussianBlur(thresh, gray, cv::Size(21, 21), cv::THRESH_BINARY); cv::GaussianBlur(gray, gray, cv::Size(21, 21), cv::THRESH_BINARY);
if(first) { if(first) {
// avg = cv::Mat::zeros(gray.size(), CV_32FC3); // avg = cv::Mat::zeros(gray.size(), CV_32FC3);
avg.release(); avg.release();
...@@ -635,23 +621,22 @@ private: ...@@ -635,23 +621,22 @@ private:
} }
#ifdef DEBUG #ifdef DEBUG
matShow3 = gray.clone(); matShow3 = avg;
matShow2 = origin; matShow2 = origin;
#endif #endif
// packetTm = chrono::system_clock::now(); // packetTm = chrono::system_clock::now();
packetTm = packetTs; packetTm = packetTs;
// TODO: AVG // TODO: AVG
// cv::accumulateWeighted(gray, avg, 0.5); // cv::accumulateWeighted(gray, avg, 0.5);
cv::absdiff(gray, avg, thresh); cv::Mat diff;
avg.release(); cv::absdiff(gray, avg, diff);
avg = gray.clone(); // if(!detect || fent < detPara.entropy) {
// return;
if(!detect || fent < detPara.entropy) { // }
return;
}
cv::threshold(thresh, gray, detPara.thre, 255, cv::THRESH_BINARY); cv::Mat thresh;
// cv::dilate(gray, thresh, cv::Mat(), cv::Point(-1,-1), 2); cv::threshold(diff, thresh, detPara.thre, 255, cv::THRESH_BINARY);
//cv::dilate(gray, thresh, cv::Mat(), cv::Point(-1,-1), 2);
#ifdef DEBUG #ifdef DEBUG
matShow1 = thresh.clone(); matShow1 = thresh.clone();
...@@ -659,14 +644,14 @@ private: ...@@ -659,14 +644,14 @@ private:
cv::findContours(thresh, cnts, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); cv::findContours(thresh, cnts, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
bool hasEvent = false; bool hasEvent = false;
int evtCnt = 0; static int evtCnt = 0;
int i = 0; int i = 0;
double area = (double)(detPara.area * imgScalor); double area = (double)(detPara.area * imgScalor);
if(area < 10) { if(area < 10) {
area = 10; area = 10;
} }
for(; i < cnts.size(); i++) { for(; i < cnts.size(); i++) {
auto _area = cv::contourArea(cnts[i]); _area = cv::contourArea(cnts[i]);
if(_area < area) { if(_area < area) {
// nothing // nothing
} }
...@@ -676,96 +661,110 @@ private: ...@@ -676,96 +661,110 @@ private:
#ifdef DEBUG #ifdef DEBUG
cv::putText(origin, "motion detected", cv::Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0,0,255),2); cv::putText(origin, "motion detected", cv::Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0,0,255),2);
#endif #endif
spdlog::info("{} motion detected: idx {}, area: {}", selfId, i, _area); //spdlog::info("{} motion detected: idx {}, area: {}", selfId, i, _area);
break; break;
} }
} //end for } //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); spdlog::debug("{} contours {} area {}, thresh {} hasEvent {}", selfId, cnts.size(), hasEvent? cv::contourArea(cnts[i]):0, detPara.area, hasEvent);
// business logic for event // business logic for event
// auto dura = chrono::duration_cast<chrono::seconds>(packetTm - evtStartTmLast).count(); // auto dura = chrono::duration_cast<chrono::seconds>(packetTm - evtStartTmLast).count();
if(hasEvent){
evtStartTmLast = packetTm;
}
long long dura = 0; long long dura = 0;
if(evtStartTmLast != 0) { if(evtStartTmLast != 0) {
dura = packetTm - evtStartTmLast; dura = packetTm - evtStartTmLast;
}else{
evtStartTmLast = packetTm;
return;
} }
switch(evtState) { static long long pktDelt = 0;
case NONE: { if(pktCnt %18 == 0){
if(hasEvent) { auto tmp = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
evtState = PRE; pktDelt = tmp - packetTm;
spdlog::info("{} state: NONE->PRE ({}, {})", selfId, dura, evtCnt);
evtCnt = 0;
evtStartTmOrig = packetTm;
}
break;
}
case PRE: {
if(hasEvent) {
if(dura > detPara.pre /*&& evtCnt < detPara.pre*/) {
spdlog::info("state: PRE->PRE ({}, {})", dura, evtCnt);
evtState = PRE;
evtStartTmOrig = packetTm;
evtCnt = 0;
} }
else if (true/*dura > detPara.pre && evtCnt >= detPara.pre*/) {
evtState = IN; switch(evtState) {
case NONE:
case PRE:
if(dura >= detPara.pre) {
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 - detPara.pre;
// }else{
// spdlog::info("state: NONE->NONE ({}, {}, {}, {}, {}, {})", this->fps, dura, frameProcessed, evtCnt, thr, _area);
// }
spdlog::info("state: NONE->NONE ({}, {}, {}, {}, {}, {}, {})", pktDelt, this->fps, dura, frameProcessed, evtCnt, thr, _area);
}else{
// if(evtState == PRE) {
// json p;
// 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;
// }
json p; json p;
spdlog::info("{} state: PRE->IN ({}, {})", selfId, dura, evtCnt); evtState = IN;
evtCnt = 0; evtStartTmOrig = packetTm - detPara.pre;
spdlog::info("{} state: NONE->IN ({}, {}, {}, {}, {}, {}, {})", selfId, pktDelt, this->fps, dura, frameProcessed, evtCnt, thr, _area);
makeEvent(EV_MSG_EVENT_MOTION_START, evtStartTmOrig); 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 {
if(dura > detPara.pre) {
evtState= NONE;
spdlog::info("{} state: PRE->NONE ({}, {})", selfId, dura, evtCnt);
evtCnt = 0; evtCnt = 0;
} frameProcessed = 0;
evtStartTmLast = packetTm;
} }
break; break;
}
case IN: { case IN: {
if(!hasEvent) { if( packetTm - evtStartTmOrig > 60 *detPara.maxDuration ) {
if(dura > (int)(detPara.post/2)) {
evtState = POST;
spdlog::info("{} state: IN->POST ({}, {})", selfId, dura, evtCnt);
evtCnt = 0;
}
}
else {
if( (packetTm - evtStartTmOrig) > (60 *detPara.maxDuration) ) {
evtStartTmOrig = packetTm; evtStartTmOrig = packetTm;
makeEvent(EV_MSG_EVENT_MOTION_END, packetTs); makeEvent(EV_MSG_EVENT_MOTION_END, packetTs);
evtCnt = 0;
makeEvent(EV_MSG_EVENT_MOTION_START, packetTs); makeEvent(EV_MSG_EVENT_MOTION_START, packetTs);
spdlog::warn("{} event video continued over {} minutes, force segmenting and continue", devSn, detPara.maxDuration); spdlog::warn("{} event video continued over {} minutes, force segmenting and continue", devSn, detPara.maxDuration);
}
spdlog::debug("{} state: IN->IN ({}, {})",selfId, dura, evtCnt); spdlog::debug("{} state: IN->IN ({}, {})",selfId, dura, evtCnt);
evtCnt = 0; evtCnt = 0;
frameProcessed = 0;
evtStartTmLast = packetTm;
}else if(dura >= detPara.post/2){
auto thr = frameProcessed/5;
if(evtCnt <= thr){
evtState = POST;
spdlog::info("{} state: IN->POST ({}, {}, {}, {}, {}, {}, {})", selfId, pktDelt, this->fps, dura, frameProcessed, evtCnt, thr, _area);
}else{
spdlog::info("{} state: IN->IN ({}, {}, {}, {}, {}, {}, {})", selfId, pktDelt, this->fps, dura, frameProcessed, evtCnt, thr, _area);
}
evtCnt = 0;
frameProcessed = 0;
evtStartTmLast = packetTm;
} }
break; break;
} }
case POST: { case POST: {
if(!hasEvent) { if(dura >= detPara.post/2){
if(dura > detPara.post) { auto thr = frameProcessed/5;
spdlog::info("state: POST->NONE ({}, {})", dura, evtCnt); if(evtCnt <= thr){
spdlog::info("{} state: POST->NONE ({}, {}, {}, {}, {}, {}, {})",selfId, pktDelt, this->fps, dura, frameProcessed, evtCnt, thr, _area);
evtState = NONE; evtState = NONE;
evtCnt = 0; makeEvent(EV_MSG_EVENT_MOTION_END, packetTs - detPara.post/2);
makeEvent(EV_MSG_EVENT_MOTION_END, packetTs); }else{
} spdlog::info("{} state: POST->IN ({}, {}, {}, {}, {}, {}, {})",selfId, pktDelt, this->fps, dura, frameProcessed, evtCnt, thr, _area);
evtState = IN;
} }
else {
spdlog::info("state: POST->IN ({}, {})", dura, evtCnt);
evtState=IN;
evtCnt = 0; evtCnt = 0;
frameProcessed = 0;
evtStartTmLast = packetTm;
} }
break; break;
} }
...@@ -776,7 +775,6 @@ protected: ...@@ -776,7 +775,6 @@ protected:
void run() void run()
{ {
bool bStopSig = false; bool bStopSig = false;
uint64_t pktCnt = 0;
zmq_msg_t msg; zmq_msg_t msg;
AVPacket packet; AVPacket packet;
json eventToSlicer; json eventToSlicer;
...@@ -876,6 +874,35 @@ protected: ...@@ -876,6 +874,35 @@ protected:
} }
} }
zmq_msg_close(&msg); zmq_msg_close(&msg);
static int _fpsDetectCnt = 0;
static auto _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) { if(pktCnt % EV_LOG_PACKET_CNT == 0) {
spdlog::info("{} seq: {}, pts: {}, dts: {}, idx: {}", selfId, pktCnt, packet.pts, packet.dts, packet.stream_index); spdlog::info("{} seq: {}, pts: {}, dts: {}, idx: {}", selfId, pktCnt, packet.pts, packet.dts, packet.stream_index);
} }
......
...@@ -840,7 +840,7 @@ protected: ...@@ -840,7 +840,7 @@ protected:
} }
// find video files // find video files
vector<string> findSlicesByRange(long tss, long tse, int offsetS, int offsetE) vector<string> findSlicesByRange(long tss, long tse, long & offsetS, long &offsetE)
{ {
vector<string> ret; vector<string> ret;
...@@ -883,6 +883,7 @@ protected: ...@@ -883,6 +883,7 @@ protected:
if(found == 1) { if(found == 1) {
string sf; string sf;
auto itr = tmp.begin(); auto itr = tmp.begin();
offsetS = tss - *itr;
for(; itr != tmp.end(); itr++) { for(; itr != tmp.end(); itr++) {
string fname = videoFileTs2Name(*itr, true); string fname = videoFileTs2Name(*itr, true);
sf += "\n\t" + this->urlOut + "/" + fname + ".mp4, " + to_string(*itr); sf += "\n\t" + this->urlOut + "/" + fname + ".mp4, " + to_string(*itr);
...@@ -1070,8 +1071,8 @@ public: ...@@ -1070,8 +1071,8 @@ public:
params["startTime"] = to_string(tss); params["startTime"] = to_string(tss);
params["endTime"] = to_string(tse); params["endTime"] = to_string(tse);
params["cameraId"] = ipcSn; params["cameraId"] = ipcSn;
params["headOffset"] = to_string(offsetS); params["headOffset"] = "0";//to_string(offsetS);
params["tailOffset"] = to_string(offsetE); params["tailOffset"] = "0";//to_string(offsetE);
params["type"] = jEvt["type"].get<string>(); params["type"] = jEvt["type"].get<string>();
json fileNames; json fileNames;
string sf; string sf;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论