bf3de932d1
Broken down the code into multiple files instead having it all in main.cpp. Also detached recording from detection by having them now run in separate threads instead of having motion detection inline with recording. this will hopefully make it so there is less missed motion events due to processing overhead. The recording loop now take advantage of FFMPEG's "-f segment" option instead of generating the clips implicitly in separated FFMPEG calls. again, all in hope to reduce missed motion events. This application have the tendency to detect motion of small insects. to prevent this it was determined with there will need to be some means of identifying objects via machine vision. there is an object detection function but it doesn't currently do anything at this time. this is something that I will be working on in the near future. created a test branch in the repository. all early, testing code will now go in this branch going forward. only fully tested, stable code will be committed to master going forward.
112 lines
2.9 KiB
C++
112 lines
2.9 KiB
C++
// 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<uchar>(Point(x, y));
|
|
auto pixB = imgB.at<uchar>(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<thread> 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;
|
|
}
|