v1.4.t1
added object detection code base on yolov5 machine vision model. also added a stat file so motion and object detection values can be monitored in real time if used with the 'watch' command.
This commit is contained in:
parent
d5a9d1f046
commit
5d12855fad
|
@ -1,3 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
mkdir -p /etc/mow
|
||||||
|
cp ./etc/yolov5s.onnx /etc/mow/yolov5s.onnx
|
||||||
|
cp ./etc/classes.txt /etc/mow/classes.txt
|
||||||
cp ./.build-mow/mow /usr/bin/mow
|
cp ./.build-mow/mow /usr/bin/mow
|
||||||
|
|
10
setup.sh
10
setup.sh
|
@ -3,11 +3,17 @@
|
||||||
apt update
|
apt update
|
||||||
apt install -y cmake g++ wget unzip git ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
|
apt install -y cmake g++ wget unzip git ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
|
||||||
cd ./src
|
cd ./src
|
||||||
git clone https://github.com/opencv/opencv.git
|
if [ -d "./opencv" ]
|
||||||
|
then
|
||||||
|
cd ./opencv
|
||||||
|
git pull origin
|
||||||
|
cd ..
|
||||||
|
else
|
||||||
|
git clone https://github.com/opencv/opencv.git
|
||||||
|
fi
|
||||||
cd ..
|
cd ..
|
||||||
mkdir -p ./.build-opencv
|
mkdir -p ./.build-opencv
|
||||||
cd ./.build-opencv
|
cd ./.build-opencv
|
||||||
cmake ../src/opencv
|
cmake ../src/opencv
|
||||||
make -j4
|
make -j4
|
||||||
make install
|
make install
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,21 @@ void rdLine(const string ¶m, const string &line, int *value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<string> loadClassList()
|
||||||
|
{
|
||||||
|
vector<string> ret;
|
||||||
|
|
||||||
|
ifstream ifs("/etc/mow/classes.txt");
|
||||||
|
string line;
|
||||||
|
|
||||||
|
while (getline(ifs, line))
|
||||||
|
{
|
||||||
|
ret.push_back(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool rdConf(shared_t *share)
|
bool rdConf(shared_t *share)
|
||||||
{
|
{
|
||||||
ifstream varFile(share->conf.c_str());
|
ifstream varFile(share->conf.c_str());
|
||||||
|
@ -209,6 +224,11 @@ bool rdConf(shared_t *share)
|
||||||
share->vidExt = "mp4";
|
share->vidExt = "mp4";
|
||||||
share->recLoopWait = false;
|
share->recLoopWait = false;
|
||||||
share->skipCmd = false;
|
share->skipCmd = false;
|
||||||
|
share->network = dnn::readNet("/etc/mow/yolov5s.onnx");
|
||||||
|
share->classNames = loadClassList();
|
||||||
|
|
||||||
|
share->network.setPreferableBackend(dnn::DNN_BACKEND_OPENCV);
|
||||||
|
share->network.setPreferableTarget(dnn::DNN_TARGET_CPU);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
55
src/common.h
55
src/common.h
|
@ -34,30 +34,42 @@ using namespace std;
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
|
|
||||||
#define BUF_SZ 10
|
#define BUF_SZ 10
|
||||||
#define APP_VER "1.4"
|
#define APP_VER "1.4.t1"
|
||||||
|
|
||||||
|
#define ST_LEN 7
|
||||||
|
#define ST_PIXDIFF 0
|
||||||
|
#define ST_BLOCK_POS_X 1
|
||||||
|
#define ST_BLOCK_POS_Y 2
|
||||||
|
#define ST_BLOCK_LEN_X 3
|
||||||
|
#define ST_BLOCK_LEN_Y 4
|
||||||
|
#define ST_CONFIDENCE 5
|
||||||
|
#define ST_CLASS_SCORE 6
|
||||||
|
|
||||||
struct shared_t
|
struct shared_t
|
||||||
{
|
{
|
||||||
string recordUrl;
|
vector<string> stat;
|
||||||
string outDir;
|
vector<string> classNames;
|
||||||
string postCmd;
|
dnn::Net network;
|
||||||
string conf;
|
string recordUrl;
|
||||||
string buffDir;
|
string outDir;
|
||||||
string concatTxtTmp;
|
string postCmd;
|
||||||
string concatShTmp;
|
string conf;
|
||||||
string createShTmp;
|
string buffDir;
|
||||||
string vidExt;
|
string concatTxtTmp;
|
||||||
bool init;
|
string concatShTmp;
|
||||||
bool recLoopWait;
|
string createShTmp;
|
||||||
bool skipCmd;
|
string vidExt;
|
||||||
int tmpId;
|
bool init;
|
||||||
int colorThresh;
|
bool recLoopWait;
|
||||||
int secs;
|
bool skipCmd;
|
||||||
int blockThresh;
|
int tmpId;
|
||||||
int blockX;
|
int colorThresh;
|
||||||
int blockY;
|
int secs;
|
||||||
int maxDays;
|
int blockThresh;
|
||||||
int retCode;
|
int blockX;
|
||||||
|
int blockY;
|
||||||
|
int maxDays;
|
||||||
|
int retCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
string genTmpFile(const string &dirOut, const string &ext, shared_t *share);
|
string genTmpFile(const string &dirOut, const string &ext, shared_t *share);
|
||||||
|
@ -77,5 +89,6 @@ bool rdConf(shared_t *share);
|
||||||
bool capPair(Mat &prev, Mat &next, VideoCapture &capture, shared_t *share);
|
bool capPair(Mat &prev, Mat &next, VideoCapture &capture, shared_t *share);
|
||||||
Mat toGray(const Mat &src);
|
Mat toGray(const Mat &src);
|
||||||
vector<string> lsFilesInDir(const string &path, const string &ext);
|
vector<string> lsFilesInDir(const string &path, const string &ext);
|
||||||
|
vector<string> loadClassList();
|
||||||
|
|
||||||
#endif // COMMON_H
|
#endif // COMMON_H
|
||||||
|
|
|
@ -30,7 +30,7 @@ void detectLoop(shared_t *share)
|
||||||
|
|
||||||
if (moDetect(fullPath, &blockArea, &blockImg, share))
|
if (moDetect(fullPath, &blockArea, &blockImg, share))
|
||||||
{
|
{
|
||||||
if (objectInImage(blockImg, blockArea))
|
if (objectInImage(blockImg, blockArea, share))
|
||||||
{
|
{
|
||||||
share->skipCmd = true;
|
share->skipCmd = true;
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,12 @@ void secDiff(Mat imgA, Mat imgB, int rows, int cols, int rowOffs, int colOffs, R
|
||||||
|
|
||||||
if (pnts >= share->blockThresh)
|
if (pnts >= share->blockThresh)
|
||||||
{
|
{
|
||||||
|
share->stat[ST_PIXDIFF] = to_string(pnts);
|
||||||
|
share->stat[ST_BLOCK_POS_X] = to_string(colOffs);
|
||||||
|
share->stat[ST_BLOCK_POS_Y] = to_string(rowOffs);
|
||||||
|
share->stat[ST_BLOCK_LEN_X] = to_string(cols);
|
||||||
|
share->stat[ST_BLOCK_LEN_Y] = to_string(rows);
|
||||||
|
|
||||||
block->x = colOffs;
|
block->x = colOffs;
|
||||||
block->y = rowOffs;
|
block->y = rowOffs;
|
||||||
|
|
||||||
|
@ -92,6 +98,8 @@ bool moDetect(const string &buffFile, Rect *block, Mat *img, shared_t *share)
|
||||||
Mat prev;
|
Mat prev;
|
||||||
Mat next;
|
Mat next;
|
||||||
|
|
||||||
|
share->stat = vector<string>(ST_LEN, string("0"));
|
||||||
|
|
||||||
while (capPair(prev, next, capture, share))
|
while (capPair(prev, next, capture, share))
|
||||||
{
|
{
|
||||||
if (imgDiff(toGray(prev), toGray(next), block, share))
|
if (imgDiff(toGray(prev), toGray(next), block, share))
|
||||||
|
@ -100,6 +108,19 @@ bool moDetect(const string &buffFile, Rect *block, Mat *img, shared_t *share)
|
||||||
mod = true; break;
|
mod = true; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ofstream file(string(cleanDir(share->buffDir) + "/stat").c_str());
|
||||||
|
|
||||||
|
file << "pix_diff: " << share->stat[ST_PIXDIFF] << endl;
|
||||||
|
file << "block_pos_x: " << share->stat[ST_BLOCK_POS_X] << endl;
|
||||||
|
file << "block_pos_y: " << share->stat[ST_BLOCK_POS_Y] << endl;
|
||||||
|
file << "block_siz_x: " << share->stat[ST_BLOCK_LEN_X] << endl;
|
||||||
|
file << "block_siz_y: " << share->stat[ST_BLOCK_LEN_Y] << endl;
|
||||||
|
file << "--object_dection:" << endl;
|
||||||
|
file << " confidence: " << share->stat[ST_CONFIDENCE] << endl;
|
||||||
|
file << " class_score: " << share->stat[ST_CLASS_SCORE] << endl;
|
||||||
|
|
||||||
|
file.close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,8 +12,46 @@
|
||||||
|
|
||||||
#include "obj_detect.h"
|
#include "obj_detect.h"
|
||||||
|
|
||||||
bool objectInImage(const Mat &image, const Rect &area)
|
bool objectInImage(const Mat &src, const Rect &area, shared_t *share)
|
||||||
{
|
{
|
||||||
// future object detection code. for now this will just return true.
|
// reference: https://github.com/doleron/yolov5-opencv-cpp-python/blob/main/cpp/yolo.cpp
|
||||||
return true;
|
Mat blockImage(src, area);
|
||||||
|
Mat blob;
|
||||||
|
|
||||||
|
dnn::blobFromImage(blockImage, blob, 1./255., Size(area.width, area.height), cv::Scalar(), true, false);
|
||||||
|
|
||||||
|
share->network.setInput(blob);
|
||||||
|
|
||||||
|
vector<Mat> outputs;
|
||||||
|
|
||||||
|
share->network.forward(outputs, share->network.getUnconnectedOutLayersNames());
|
||||||
|
|
||||||
|
float *data = (float *)outputs[0].data;
|
||||||
|
|
||||||
|
for (int i = 0; i < 25200; ++i)
|
||||||
|
{
|
||||||
|
// confidence level data[4];
|
||||||
|
if (data[4] >= 0.4)
|
||||||
|
{
|
||||||
|
float *classesScores = data + 5;
|
||||||
|
|
||||||
|
Mat scores(1, share->classNames.size(), CV_32FC1, classesScores);
|
||||||
|
Point classId;
|
||||||
|
double maxClassScore;
|
||||||
|
|
||||||
|
minMaxLoc(scores, 0, &maxClassScore, 0, &classId);
|
||||||
|
|
||||||
|
share->stat[ST_CONFIDENCE] = to_string(data[4]);
|
||||||
|
share->stat[ST_CLASS_SCORE] = to_string(maxClassScore);
|
||||||
|
|
||||||
|
if (maxClassScore > 0.2)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data += 85;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,6 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
bool objectInImage(const Mat &image, const Rect &area);
|
bool objectInImage(const Mat &image, const Rect &area, shared_t *share);
|
||||||
|
|
||||||
#endif // OBJ_DETECT_H
|
#endif // OBJ_DETECT_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user