// 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 pixDiff(const uchar &pixA, const uchar &pixB, shared_t *share) { auto diff = 0; if (pixA > pixB) diff = pixA - pixB; if (pixB > pixA) diff = pixB - pixA; if (diff < share->colorThresh) { diff = 0; } return diff != 0; } void secDiff(Mat imgA, Mat imgB, int rows, int cols, int rowOffs, int colOffs, Rect *block, bool *mod, shared_t *share) { auto pnts = 0; for (auto y = rowOffs; y < rows; y++) { for (auto x = colOffs; x < cols; x++) { auto pixA = imgA.at(Point(x, y)); auto pixB = imgB.at(Point(x, y)); if (pixDiff(pixA, pixB, share)) { pnts += 1; if (pnts >= share->blockThresh) { block->x = colOffs; block->y = rowOffs; block->height = rows; block->width = cols; *mod = true; return; } } } } } bool imgDiff(Mat prev, Mat next, Rect *block, shared_t *share) { auto numOfXBlocks = prev.cols / share->blockX; auto numOfYBlocks = prev.rows / share->blockY; auto moInBlock = false; vector threads; for (auto x = 0; (x < numOfXBlocks) && !moInBlock; x += share->blockX) { for (auto y = 0; (y < numOfYBlocks) && !moInBlock; y += share->blockY) { threads.push_back(thread(secDiff, prev, next, share->blockY, share->blockX, y, x, block, &moInBlock, share)); } } for (auto &&thr : threads) { thr.join(); } return moInBlock; } bool moDetect(const string &buffFile, Rect *block, Mat *img, shared_t *share) { auto mod = false; VideoCapture capture(buffFile.c_str(), CAP_FFMPEG); if (capture.isOpened()) { Mat prev; Mat next; while (capPair(prev, next, capture, share)) { if (imgDiff(toGray(prev), toGray(next), block, share)) { *img = next; mod = true; break; } } } else { cerr << "err: Could not open buff file: " << buffFile << " for reading. check formatting/permissions." << endl; cerr << " Also check if opencv was compiled with FFMPEG encoding enabled." << endl; } return mod; }