// 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 &score, shared_t *share) { Mat prevGray; Mat nextGray; cvtColor(prev, prevGray, COLOR_BGR2GRAY); cvtColor(next, nextGray, COLOR_BGR2GRAY); Mat diff; absdiff(prevGray, nextGray, diff); threshold(diff, diff, share->pixThresh, 255, THRESH_BINARY); score = countNonZero(diff); detLog("diff_score: " + QString::number(score) + " thresh: " + QString::number(share->imgThresh), share); return score >= share->imgThresh; } bool moDetect(const QString &buffFile, QThread *thr, shared_t *share) { auto score = 0; auto mod = false; detLog("stream_clip: " + buffFile, share); VideoCapture capture; if (!capture.open(buffFile.toUtf8().data(), CAP_FFMPEG)) { thr->usleep(500); capture.open(buffFile.toUtf8().data(), CAP_FFMPEG); } if (capture.isOpened()) { Mat prev; Mat next; int fps = capture.get(cv::CAP_PROP_FPS); for (auto gap = 0, frm = fps; capture.grab(); ++gap, ++frm) { if (frm == fps) thr->sleep(1); frm = 1; if (prev.empty()) { capture.retrieve(prev); } else if (gap == (share->frameGap - 1)) { capture.retrieve(next); if (!next.empty()) { if (imgDiff(prev, next, score, share)) { mod = true; if (share->maxScore <= score) { share->maxScore = score; resize(next, share->curEvent.thumbnail, Size(720, 480), INTER_LINEAR); } } } prev = next.clone(); gap = 0; next.release(); } else { capture.grab(); } } } else { detLog("err: failed to open: " + buffFile + " after 500 msecs. giving up.", share); } capture.release(); return mod; }