// This file is part of Motion Watch. // Motion Watch is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Motion Watch is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. #include "mo_detect.h" bool imgDiff(const Mat &prev, const Mat &next, int &diffScore, shared_t *share) { Mat diff; absdiff(prev, next, diff); threshold(diff, diff, share->pixThresh, 255, THRESH_BINARY); diffScore = countNonZero(diff); return diffScore >= share->imgThresh; } Mat frameFF(VideoCapture *cap, int gap) { Mat ret; if (gap == 0) gap = 1; for (int i = 0; i < gap; ++i) { cap->grab(); } cap->retrieve(ret); if (!ret.empty()) { cvtColor(ret, ret, COLOR_BGR2GRAY); } return ret; } void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share) { auto dayStr = genTimeStr("%Y-%m-%d"); auto timStr = genTimeStr("%H%M%S"); auto outDir = cleanDir(share->outDir) + "/" + dayStr; if (!exists(outDir)) { enforceMaxDays(share->outDir, share); } auto vidOut = genDstFile(outDir, timStr.c_str(), "." + share->vidExt); auto imgOut = genDstFile(outDir, timStr.c_str(), ".jpg"); detLog("write_out_vid: " + vidOut, share); detLog("write_out_img: " + imgOut, share); detLog("remove_file: " + buffFile, share); enforceMaxClips(outDir, share); copy_file(buffFile.c_str(), vidOut.c_str()); remove(buffFile.c_str()); imwrite(imgOut.c_str(), vidThumb); genHTMLvid(vidOut, share); genHTMLul(outDir, share->camName + ": " + dayStr, share); genHTMLul(share->outDir, share->camName, share); } bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share) { auto mod = false; VideoCapture capture(buffFile.c_str()); if (capture.isOpened()) { Mat prev; Mat next; int diff = 0; int maxDiff = 0; int frameGaps = 0; do { if (prev.empty()) prev = frameFF(&capture, 1); else prev = next.clone(); next = frameFF(&capture, share->frameGap); if (imgDiff(prev, next, diff, share)) { resize(next, vidThumb, Size(1280, 720), INTER_LINEAR); if (diff > maxDiff) { maxDiff = diff; } mod = true; break; } frameGaps++; } while (!prev.empty() && !next.empty()); detLog("scanned_buff_file = " + buffFile + " max_score = " + to_string(maxDiff) + " frame_gaps = " + to_string(frameGaps), share); } else { detLog("failed to open buff file: " + buffFile + " for reading.", share); detLog("check formatting/permissions.", share); detLog("also check if opencv was compiled with FFMPEG encoding enabled.", share); } return mod; }