Added Monitor scaffolding and a skeleton benchmark for DetectMotion.
This commit is contained in:
parent
3723e136b1
commit
305af08112
|
@ -20,11 +20,13 @@
|
|||
#include <memory>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zm_config.h"
|
||||
#include "zm_image.h"
|
||||
#include "zm_monitor.h"
|
||||
#include "zm_utils.h"
|
||||
#include "zm_zone.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Generate a greyscale image that simulates a delta that can be fed to
|
||||
// Zone::CheckAlarms.
|
||||
|
@ -40,7 +42,7 @@
|
|||
// Return:
|
||||
// An image with all pixels initialized to values in the [minVal,maxVal] range.
|
||||
//
|
||||
std::shared_ptr<Image> GenerateDeltaImage(
|
||||
std::shared_ptr<Image> GenerateRandomImage(
|
||||
int minVal,
|
||||
int maxVal,
|
||||
int width = 3840,
|
||||
|
@ -60,16 +62,159 @@ std::shared_ptr<Image> GenerateDeltaImage(
|
|||
row[x] = (rand() * range) / RAND_MAX + minVal;
|
||||
}
|
||||
|
||||
return image;
|
||||
return std::shared_ptr<Image>(image);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This is used to help rig up tests of Monitor.
|
||||
//
|
||||
class TestMonitor : public Monitor
|
||||
{
|
||||
public:
|
||||
TestMonitor(int width, int height) {
|
||||
cur_zone_id = 111;
|
||||
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
|
||||
// Create a dummy ref_image.
|
||||
std::shared_ptr<Image> tempImage = GenerateRandomImage(0, 0, width, height);
|
||||
ref_image = *tempImage.get();
|
||||
|
||||
shared_data = &temp_shared_data;
|
||||
}
|
||||
|
||||
//
|
||||
// Add a new zone to this monitor.
|
||||
//
|
||||
// Args:
|
||||
// checkMethod: This controls how this zone will actually do motion detection.
|
||||
//
|
||||
// p_filter_box: The size of the filter to use.
|
||||
//
|
||||
void AddZone(Zone::CheckMethod checkMethod, const Vector2 &p_filter_box=Vector2(5,5)) {
|
||||
const int p_min_pixel_threshold = 50;
|
||||
const int p_max_pixel_threshold = 255;
|
||||
const int p_min_alarm_pixels = 1000;
|
||||
const int p_max_alarm_pixels = 10000000;
|
||||
|
||||
const int zone_id = cur_zone_id++;
|
||||
const std::string zone_label = std::string("zone_") + std::to_string(zone_id);
|
||||
const Zone::ZoneType zoneType = Zone::ZoneType::ACTIVE;
|
||||
const Polygon poly({
|
||||
Vector2(0, 0),
|
||||
Vector2(width-1, 0),
|
||||
Vector2(width-1, height-1),
|
||||
Vector2(0, height-1)});
|
||||
|
||||
Zone zone(
|
||||
this,
|
||||
zone_id,
|
||||
zone_label.c_str(),
|
||||
zoneType,
|
||||
poly,
|
||||
kRGBGreen,
|
||||
Zone::CheckMethod::FILTERED_PIXELS,
|
||||
p_min_pixel_threshold,
|
||||
p_max_pixel_threshold,
|
||||
p_min_alarm_pixels,
|
||||
p_max_alarm_pixels,
|
||||
p_filter_box
|
||||
);
|
||||
zones.push_back(zone);
|
||||
}
|
||||
|
||||
void SetRefImage(const Image *image) {
|
||||
ref_image = *image;
|
||||
}
|
||||
|
||||
private:
|
||||
SharedData temp_shared_data;
|
||||
int cur_zone_id;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CounterInfo {
|
||||
public:
|
||||
CounterInfo(
|
||||
const std::chrono::microseconds &in_timer,
|
||||
const std::string &in_label) :
|
||||
timer(in_timer),
|
||||
label(in_label)
|
||||
{
|
||||
}
|
||||
|
||||
const std::chrono::microseconds timer;
|
||||
const std::string label;
|
||||
};
|
||||
|
||||
//
|
||||
// Print out a table of timing results.
|
||||
//
|
||||
// Args:
|
||||
// counters: The list of counters to print out, and info about how to format it.
|
||||
//
|
||||
void PrintCounters(std::vector<CounterInfo> counters) {
|
||||
for (const auto counter : counters) {
|
||||
printf("%s: %lims\n", counter.label.c_str(), counter.timer.count());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Run zone benchmarks on the given image.
|
||||
//
|
||||
// Args:
|
||||
// label: A label to be printed before the output.
|
||||
//
|
||||
// image: The image to run the tests on.
|
||||
//
|
||||
void RunZoneBenchmark(const char *label, std::shared_ptr<Image> image) {
|
||||
// Create a monitor to use for the benchmark. Give it 1 zone that uses
|
||||
// a 5x5 filter.
|
||||
TestMonitor testMonitor(image->Width(), image->Height());
|
||||
testMonitor.AddZone(Zone::CheckMethod::FILTERED_PIXELS, Vector2(5,5));
|
||||
|
||||
// Generate a black image to use as the reference image.
|
||||
std::shared_ptr<Image> blackImage = GenerateRandomImage(
|
||||
0, 0, image->Width(), image->Height());
|
||||
testMonitor.SetRefImage(blackImage.get());
|
||||
|
||||
std::chrono::microseconds totalTimeTaken(0);
|
||||
|
||||
// Run a series of passes over DetectMotion.
|
||||
const int numPasses = 10;
|
||||
for (int i=0; i < numPasses; i++)
|
||||
{
|
||||
printf("\r(%d / %d) ", i+1, numPasses);
|
||||
fflush(stdout);
|
||||
|
||||
Event::StringSet zoneSet;
|
||||
testMonitor.DetectMotion(*image.get(), zoneSet);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("------- %s -------\n", label);
|
||||
PrintCounters({
|
||||
CounterInfo(totalTimeTaken, "Total zone benchmark time")});
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
srand(111);
|
||||
|
||||
RunZoneBenchmark("0%% delta", GenerateDeltaImage(0, 0));
|
||||
RunZoneBenchmark("50%% delta", GenerateDeltaImage(0, 255));
|
||||
RunZoneBenchmark("100%% delta", GenerateDeltaImage(255, 255));
|
||||
// Init global stuff that we need.
|
||||
config.font_file_location = "../fonts/default.zmfnt";
|
||||
config.event_close_mode = "time";
|
||||
config.cpu_extensions = 1;
|
||||
|
||||
// Detect SSE version.
|
||||
HwCapsDetect();
|
||||
|
||||
RunZoneBenchmark("0%% delta", GenerateRandomImage(0, 0));
|
||||
RunZoneBenchmark("50%% delta", GenerateRandomImage(0, 255));
|
||||
RunZoneBenchmark("100%% delta", GenerateRandomImage(255, 255));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue