Set a reference image for each zone
This commit is contained in:
parent
0d430b5f4f
commit
217aafee5a
|
@ -311,8 +311,6 @@ Monitor::Monitor(
|
|||
alarm_ref_blend_perc( p_alarm_ref_blend_perc ),
|
||||
track_motion( p_track_motion ),
|
||||
signal_check_colour( p_signal_check_colour ),
|
||||
delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ),
|
||||
ref_image( width, height, p_camera->Colours(), p_camera->SubpixelOrder() ),
|
||||
purpose( p_purpose ),
|
||||
last_motion_score(0),
|
||||
camera( p_camera ),
|
||||
|
@ -484,7 +482,6 @@ Monitor::Monitor(
|
|||
Warning( "Waiting for capture daemon" );
|
||||
sleep( 1 );
|
||||
}
|
||||
ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize());
|
||||
|
||||
n_linked_monitors = 0;
|
||||
linked_monitors = 0;
|
||||
|
@ -1217,7 +1214,10 @@ bool Monitor::Analyse()
|
|||
{
|
||||
Info( "Received resume indication at count %d", image_count );
|
||||
shared_data->active = true;
|
||||
ref_image = *snap_image;
|
||||
for ( int n_zone = 0; n_zone < n_zones; n_zone++ )
|
||||
{
|
||||
zones[n_zone]->SetRefImage(*snap_image);
|
||||
}
|
||||
ready_count = image_count+(warmup_count/2);
|
||||
shared_data->alarm_x = shared_data->alarm_y = -1;
|
||||
}
|
||||
|
@ -1228,7 +1228,10 @@ bool Monitor::Analyse()
|
|||
{
|
||||
Info( "Auto resuming at count %d", image_count );
|
||||
shared_data->active = true;
|
||||
ref_image = *snap_image;
|
||||
for ( int n_zone = 0; n_zone < n_zones; n_zone++ )
|
||||
{
|
||||
zones[n_zone]->SetRefImage(*snap_image);
|
||||
}
|
||||
ready_count = image_count+(warmup_count/2);
|
||||
auto_resume_time = 0;
|
||||
}
|
||||
|
@ -1300,32 +1303,36 @@ bool Monitor::Analyse()
|
|||
noteSetMap[SIGNAL_CAUSE] = noteSet;
|
||||
shared_data->state = state = IDLE;
|
||||
shared_data->active = signal;
|
||||
ref_image = *snap_image;
|
||||
for ( int n_zone = 0; n_zone < n_zones; n_zone++ )
|
||||
{
|
||||
zones[n_zone]->SetRefImage(*snap_image);
|
||||
}
|
||||
}
|
||||
else if ( signal && Active() && (function == MODECT || function == MOCORD) )
|
||||
{
|
||||
Event::StringSet zoneSet;
|
||||
int motion_score = last_motion_score;
|
||||
unsigned int motion_score = last_motion_score;
|
||||
bool alarm = false;
|
||||
if ( !(image_count % (motion_frame_skip+1) ) )
|
||||
{
|
||||
// Get new score.
|
||||
motion_score = last_motion_score = DetectMotion( *snap_image, zoneSet );
|
||||
alarm = DetectMotion( *snap_image, zoneSet, motion_score );
|
||||
last_motion_score = motion_score;
|
||||
}
|
||||
//int motion_score = DetectBlack( *snap_image, zoneSet );
|
||||
if ( motion_score )
|
||||
if ( alarm )
|
||||
{
|
||||
if ( !event )
|
||||
if ( motion_score )
|
||||
{
|
||||
score += motion_score;
|
||||
if ( cause.length() )
|
||||
cause += ", ";
|
||||
cause += MOTION_CAUSE;
|
||||
if ( !event )
|
||||
{
|
||||
if ( cause.length() )
|
||||
cause += ", ";
|
||||
cause += MOTION_CAUSE;
|
||||
}
|
||||
noteSetMap[MOTION_CAUSE] = zoneSet;
|
||||
}
|
||||
else
|
||||
{
|
||||
score += motion_score;
|
||||
}
|
||||
noteSetMap[MOTION_CAUSE] = zoneSet;
|
||||
|
||||
}
|
||||
shared_data->active = signal;
|
||||
|
@ -1617,10 +1624,10 @@ bool Monitor::Analyse()
|
|||
}
|
||||
if ( (!signal_change && signal) && (function == MODECT || function == MOCORD) )
|
||||
{
|
||||
if ( state == ALARM ) {
|
||||
ref_image.Blend( *snap_image, alarm_ref_blend_perc );
|
||||
} else {
|
||||
ref_image.Blend( *snap_image, ref_blend_perc );
|
||||
int ref_blend = ( state == ALARM ) ? alarm_ref_blend_perc : ref_blend_perc;
|
||||
for ( int n_zone = 0; n_zone < n_zones; n_zone++ )
|
||||
{
|
||||
zones[n_zone]->BlendRefImage( *snap_image, ref_blend );
|
||||
}
|
||||
}
|
||||
last_signal = signal;
|
||||
|
@ -3166,33 +3173,31 @@ unsigned int Monitor::DetectBlack(const Image &comp_image, Event::StringSet &zon
|
|||
|
||||
|
||||
|
||||
unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &zoneSet )
|
||||
unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &zoneSet, unsigned int &score )
|
||||
{
|
||||
bool alarm = false;
|
||||
unsigned int score = 0;
|
||||
score = 0;
|
||||
|
||||
if ( n_zones <= 0 ) return( alarm );
|
||||
|
||||
if ( config.record_diag_images )
|
||||
for ( int n_zone = 0; n_zone < n_zones; n_zone++ )
|
||||
{
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
if ( !diag_path[0] )
|
||||
Zone *zone = zones[n_zone];
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-r.jpg", config.dir_events, id );
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-r.jpg", config.dir_events, id, zone->Id() );
|
||||
zone->WriteRefImage( diag_path );
|
||||
}
|
||||
ref_image.WriteJpeg( diag_path );
|
||||
}
|
||||
|
||||
ref_image.Delta( comp_image, &delta_image);
|
||||
zone->SetDeltaImage( comp_image );
|
||||
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
if ( !diag_path[0] )
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-d.jpg", config.dir_events, id );
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-d.jpg", config.dir_events, id, zone->Id() );
|
||||
zone->WriteDeltaImage( diag_path );
|
||||
}
|
||||
delta_image.WriteJpeg( diag_path );
|
||||
}
|
||||
|
||||
// Blank out all exclusion zones
|
||||
|
@ -3207,7 +3212,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
continue;
|
||||
}
|
||||
Debug( 3, "Blanking inactive zone %s", zone->Label() );
|
||||
delta_image.Fill( RGB_BLACK, zone->GetPolygon() );
|
||||
zone->FillDeltaImage( RGB_BLACK );
|
||||
}
|
||||
|
||||
// Check preclusive zones first
|
||||
|
@ -3221,13 +3226,16 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
int old_zone_score = zone->Score();
|
||||
bool old_zone_alarmed = zone->Alarmed();
|
||||
Debug( 3, "Checking preclusive zone %s - old score: %d, state: %s", zone->Label(),old_zone_score, zone->Alarmed()?"alarmed":"quiet" );
|
||||
if ( zone->CheckAlarms( &delta_image ) )
|
||||
if ( zone->CheckAlarms( &comp_image ) )
|
||||
{
|
||||
alarm = true;
|
||||
score += zone->Score();
|
||||
zone->SetAlarm();
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( zone->Label() );
|
||||
if ( !zone->IsPostProcEnabled() )
|
||||
{
|
||||
zone->SetAlarm();
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( ("[Zone " + std::string(zone->Label()) + "]\n").c_str() );
|
||||
}
|
||||
//zone->ResetStats();
|
||||
} else {
|
||||
// check if end of alarm
|
||||
|
@ -3265,24 +3273,26 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
continue;
|
||||
}
|
||||
Debug( 3, "Checking active zone %s", zone->Label() );
|
||||
if ( zone->CheckAlarms( &delta_image ) )
|
||||
if ( zone->CheckAlarms( &comp_image ) )
|
||||
{
|
||||
alarm = true;
|
||||
score += zone->Score();
|
||||
zone->SetAlarm();
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( zone->Label() );
|
||||
if ( config.opt_control && track_motion )
|
||||
score += zone->Score();
|
||||
if ( !zone->IsPostProcEnabled() )
|
||||
{
|
||||
if ( (int)zone->Score() > top_score )
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( ("[Zone " + std::string(zone->Label()) + "]\n").c_str() );
|
||||
if ( config.opt_control && track_motion )
|
||||
{
|
||||
top_score = zone->Score();
|
||||
alarm_centre = zone->GetAlarmCentre();
|
||||
if ( (int)zone->Score() > top_score )
|
||||
{
|
||||
top_score = zone->Score();
|
||||
alarm_centre = zone->GetAlarmCentre();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( alarm )
|
||||
{
|
||||
for ( int n_zone = 0; n_zone < n_zones; n_zone++ )
|
||||
|
@ -3293,19 +3303,22 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
continue;
|
||||
}
|
||||
Debug( 3, "Checking inclusive zone %s", zone->Label() );
|
||||
if ( zone->CheckAlarms( &delta_image ) )
|
||||
if ( zone->CheckAlarms( &comp_image ) )
|
||||
{
|
||||
alarm = true;
|
||||
score += zone->Score();
|
||||
zone->SetAlarm();
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( zone->Label() );
|
||||
if ( config.opt_control && track_motion )
|
||||
score += zone->Score();
|
||||
if ( !zone->IsPostProcEnabled() )
|
||||
{
|
||||
if ( zone->Score() > (unsigned int)top_score )
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( ("[Zone " + std::string(zone->Label()) + "]\n").c_str() );
|
||||
if ( config.opt_control && track_motion )
|
||||
{
|
||||
top_score = zone->Score();
|
||||
alarm_centre = zone->GetAlarmCentre();
|
||||
if ( zone->Score() > (unsigned int)top_score )
|
||||
{
|
||||
top_score = zone->Score();
|
||||
alarm_centre = zone->GetAlarmCentre();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3322,13 +3335,16 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
continue;
|
||||
}
|
||||
Debug( 3, "Checking exclusive zone %s", zone->Label() );
|
||||
if ( zone->CheckAlarms( &delta_image ) )
|
||||
if ( zone->CheckAlarms( &comp_image ) )
|
||||
{
|
||||
alarm = true;
|
||||
score += zone->Score();
|
||||
zone->SetAlarm();
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( zone->Label() );
|
||||
score += zone->Score();
|
||||
if ( !zone->IsPostProcEnabled() )
|
||||
{
|
||||
Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() );
|
||||
zoneSet.insert( ("[Zone " + std::string(zone->Label()) + "]\n").c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3346,9 +3362,8 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
shared_data->alarm_x = shared_data->alarm_y = -1;
|
||||
}
|
||||
|
||||
// This is a small and innocent hack to prevent scores of 0 being returned in alarm state
|
||||
return( score?score:alarm );
|
||||
}
|
||||
return alarm;
|
||||
}
|
||||
|
||||
bool Monitor::DumpSettings( char *output, bool verbose )
|
||||
{
|
||||
|
|
|
@ -244,8 +244,6 @@ protected:
|
|||
Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected
|
||||
|
||||
double fps;
|
||||
Image delta_image;
|
||||
Image ref_image;
|
||||
|
||||
Purpose purpose; // What this monitor has been created to do
|
||||
int event_count;
|
||||
|
@ -385,6 +383,7 @@ public:
|
|||
}
|
||||
|
||||
unsigned int DetectMotion( const Image &comp_image, Event::StringSet &zoneSet );
|
||||
unsigned int DetectMotion( const Image &comp_image, Event::StringSet &zoneSet, unsigned int &score );
|
||||
// DetectBlack seems to be unused. Check it on zm_monitor.cpp for more info.
|
||||
//unsigned int DetectBlack( const Image &comp_image, Event::StringSet &zoneSet );
|
||||
bool CheckSignal( const Image *image );
|
||||
|
|
140
src/zm_zone.cpp
140
src/zm_zone.cpp
|
@ -60,10 +60,20 @@ void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_
|
|||
max_blob_size = 0;
|
||||
image = 0;
|
||||
score = 0;
|
||||
text = "";
|
||||
post_proc_enabled = false;
|
||||
post_proc_in_progress = false;
|
||||
include_nat_det = true;
|
||||
reinit_nat_det = false;
|
||||
|
||||
overload_count = 0;
|
||||
extend_alarm_count = 0;
|
||||
|
||||
delta_image = Image( monitor->Width(), monitor->Height(), ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE );
|
||||
ref_image = Image( monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder());
|
||||
bl_image = Image( monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder());
|
||||
bl_image.Fill( RGB_BLACK );
|
||||
|
||||
pg_image = new Image( monitor->Width(), monitor->Height(), 1, ZM_SUBPIX_ORDER_NONE);
|
||||
pg_image->Clear();
|
||||
pg_image->Fill( 0xff, polygon );
|
||||
|
@ -91,14 +101,10 @@ void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( config.record_diag_images )
|
||||
if ( config.record_diag_images && (id > 0))
|
||||
{
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
if ( !diag_path[0] )
|
||||
{
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-poly.jpg", config.dir_events, monitor->Name(), id);
|
||||
}
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-poly.jpg", config.dir_events, monitor->Name(), id);
|
||||
pg_image->WriteJpeg( diag_path );
|
||||
}
|
||||
}
|
||||
|
@ -142,6 +148,37 @@ void Zone::SetScore(unsigned int nScore)
|
|||
score = nScore;
|
||||
}
|
||||
|
||||
void Zone::SetText(std::string sText)
|
||||
{
|
||||
text = "[Zone ";
|
||||
text += label;
|
||||
text += "]\n" + sText;
|
||||
}
|
||||
|
||||
void Zone::AssignRefImage( unsigned int p_width, unsigned int p_height, unsigned int p_colours, unsigned int p_subpixelorder, const uint8_t* new_buffer, const size_t buffer_size )
|
||||
{
|
||||
ref_image.Assign( p_width, p_height, p_colours, p_subpixelorder, new_buffer, buffer_size);
|
||||
}
|
||||
|
||||
void Zone::SetRefImage(const Image &srcImage)
|
||||
{
|
||||
ref_image = srcImage;
|
||||
}
|
||||
|
||||
void Zone::BlendRefImage( const Image &srcImage, int transparency )
|
||||
{
|
||||
ref_image.Blend( srcImage, transparency );
|
||||
}
|
||||
|
||||
void Zone::SetDeltaImage( const Image &srcImage )
|
||||
{
|
||||
ref_image.Delta( srcImage, &delta_image );
|
||||
}
|
||||
|
||||
void Zone::FillDeltaImage( Rgb colour )
|
||||
{
|
||||
delta_image.Fill( colour, polygon);
|
||||
}
|
||||
|
||||
void Zone::SetAlarmImage(const Image* srcImage)
|
||||
{
|
||||
|
@ -149,6 +186,16 @@ void Zone::SetAlarmImage(const Image* srcImage)
|
|||
image = new Image(*srcImage);
|
||||
}
|
||||
|
||||
bool Zone::WriteRefImage( const char *filename, int quality_override ) const
|
||||
{
|
||||
return ref_image.WriteJpeg( filename, quality_override );
|
||||
}
|
||||
|
||||
bool Zone::WriteDeltaImage( const char *filename, int quality_override ) const
|
||||
{
|
||||
return delta_image.WriteJpeg( filename, quality_override );
|
||||
}
|
||||
|
||||
int Zone::GetOverloadCount()
|
||||
{
|
||||
return overload_count;
|
||||
|
@ -194,9 +241,33 @@ bool Zone::CheckExtendAlarmCount()
|
|||
|
||||
//===========================================================================
|
||||
|
||||
void Zone::SetConfig( zConf zone_conf )
|
||||
{
|
||||
post_proc_enabled = zone_conf.RequireNatDet;
|
||||
include_nat_det = zone_conf.IncludeNatDet;
|
||||
reinit_nat_det = zone_conf.ReInitNatDet;
|
||||
|
||||
if ( post_proc_enabled ) {
|
||||
std::string sMessage;
|
||||
if ( include_nat_det ) {
|
||||
sMessage = "(native detection included";
|
||||
}
|
||||
if ( reinit_nat_det ) {
|
||||
if (sMessage.empty()) {
|
||||
sMessage = "(native detection will be reinitialized";
|
||||
} else {
|
||||
sMessage += ", reinitialization is required";
|
||||
}
|
||||
}
|
||||
if (!sMessage.empty()) {
|
||||
sMessage += ")";
|
||||
}
|
||||
Info("Post processing enabled for zone '%s' %s", label, sMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Zone::CheckAlarms( const Image *delta_image )
|
||||
bool Zone::CheckAlarms( const Image *comp_image )
|
||||
{
|
||||
ResetStats();
|
||||
|
||||
|
@ -205,12 +276,13 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
Info( "In overload mode, %d frames of %d remaining", overload_count, overload_frames );
|
||||
Debug( 4, "In overload mode, %d frames of %d remaining", overload_count, overload_frames );
|
||||
overload_count--;
|
||||
post_proc_in_progress = false;
|
||||
return( false );
|
||||
}
|
||||
|
||||
delete image;
|
||||
// Get the difference image
|
||||
Image *diff_image = image = new Image( *delta_image );
|
||||
Image *diff_image = image = new Image( delta_image );
|
||||
int diff_width = diff_image->Width();
|
||||
uint8_t* diff_buff = (uint8_t*)diff_image->Buffer();
|
||||
uint8_t* pdiff;
|
||||
|
@ -245,10 +317,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if ( config.record_diag_images )
|
||||
{
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
if ( !diag_path[0] )
|
||||
{
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-%d.jpg", config.dir_events, monitor->Name(), id, 1 );
|
||||
}
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-%d.jpg", config.dir_events, monitor->Name(), id, 1 );
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
|
||||
|
@ -259,14 +328,17 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if( alarm_pixels ) {
|
||||
if( min_alarm_pixels && (alarm_pixels < (unsigned int)min_alarm_pixels) ) {
|
||||
/* Not enough pixels alarmed */
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
} else if( max_alarm_pixels && (alarm_pixels > (unsigned int)max_alarm_pixels) ) {
|
||||
/* Too many pixels alarmed */
|
||||
overload_count = overload_frames;
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
/* No alarmed pixels */
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
@ -342,10 +414,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if ( config.record_diag_images )
|
||||
{
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
if ( !diag_path[0] )
|
||||
{
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 2 );
|
||||
}
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 2 );
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
|
||||
|
@ -354,14 +423,17 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if( alarm_filter_pixels ) {
|
||||
if( min_filter_pixels && (alarm_filter_pixels < min_filter_pixels) ) {
|
||||
/* Not enough pixels alarmed */
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
} else if( max_filter_pixels && (alarm_filter_pixels > max_filter_pixels) ) {
|
||||
/* Too many pixels alarmed */
|
||||
overload_count = overload_frames;
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
/* No filtered pixels */
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
@ -583,15 +655,13 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if ( config.record_diag_images )
|
||||
{
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
if ( !diag_path[0] )
|
||||
{
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 3 );
|
||||
}
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 3 );
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
|
||||
if ( !alarm_blobs )
|
||||
{
|
||||
post_proc_in_progress = false;
|
||||
return( false );
|
||||
}
|
||||
|
||||
|
@ -642,10 +712,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if ( config.record_diag_images )
|
||||
{
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
if ( !diag_path[0] )
|
||||
{
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 4 );
|
||||
}
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 4 );
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
Debug( 5, "Got %d blob pixels, %d blobs, need %d -> %d, %d -> %d", alarm_blob_pixels, alarm_blobs, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs );
|
||||
|
@ -653,14 +720,17 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if( alarm_blobs ) {
|
||||
if( min_blobs && (alarm_blobs < min_blobs) ) {
|
||||
/* Not enough pixels alarmed */
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
} else if(max_blobs && (alarm_blobs > max_blobs) ) {
|
||||
/* Too many pixels alarmed */
|
||||
overload_count = overload_frames;
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
/* No blobs */
|
||||
post_proc_in_progress = false;
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
@ -797,13 +867,23 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( monitor->Colours() == ZM_COLOUR_GRAY8 ) {
|
||||
image = diff_image->HighlightEdges( alarm_rgb, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB, &polygon.Extent() );
|
||||
} else {
|
||||
image = diff_image->HighlightEdges( alarm_rgb, monitor->Colours(), monitor->SubpixelOrder(), &polygon.Extent() );
|
||||
if ( post_proc_enabled ) {
|
||||
post_proc_in_progress = true;
|
||||
}
|
||||
if ( include_nat_det ) {
|
||||
if( monitor->Colours() == ZM_COLOUR_GRAY8 ) {
|
||||
image = diff_image->HighlightEdges( alarm_rgb, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB, &polygon.Extent() );
|
||||
} else {
|
||||
image = diff_image->HighlightEdges( alarm_rgb, monitor->Colours(), monitor->SubpixelOrder(), &polygon.Extent() );
|
||||
}
|
||||
} else {
|
||||
score = 0;
|
||||
image = new Image( bl_image );
|
||||
}
|
||||
// Update reference image if required
|
||||
if ( reinit_nat_det ) {
|
||||
ref_image = *comp_image;
|
||||
}
|
||||
|
||||
// Only need to delete this when 'image' becomes detached and points somewhere else
|
||||
delete diff_image;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,19 @@
|
|||
|
||||
class Monitor;
|
||||
|
||||
//! A structure to store the post processing configuration for the zone
|
||||
struct zConf
|
||||
{
|
||||
bool RequireNatDet;
|
||||
bool IncludeNatDet;
|
||||
bool ReInitNatDet;
|
||||
zConf():
|
||||
RequireNatDet(false),
|
||||
IncludeNatDet(false),
|
||||
ReInitNatDet(false)
|
||||
{}
|
||||
};
|
||||
|
||||
//
|
||||
// This describes a 'zone', or an area of an image that has certain
|
||||
// detection characteristics.
|
||||
|
@ -87,12 +100,20 @@ protected:
|
|||
Box alarm_box;
|
||||
Coord alarm_centre;
|
||||
unsigned int score;
|
||||
std::string text;
|
||||
Image *pg_image;
|
||||
Range *ranges;
|
||||
Image *image;
|
||||
Image delta_image;
|
||||
Image ref_image;
|
||||
Image bl_image;
|
||||
|
||||
int overload_count;
|
||||
int extend_alarm_count;
|
||||
bool post_proc_enabled;
|
||||
bool include_nat_det;
|
||||
bool reinit_nat_det;
|
||||
bool post_proc_in_progress;
|
||||
|
||||
protected:
|
||||
void Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold, int p_max_pixel_threshold, int p_min_alarm_pixels, int p_max_alarm_pixels, const Coord &p_filter_box, int p_min_filter_pixels, int p_max_filter_pixels, int p_min_blob_pixels, int p_max_blob_pixels, int p_min_blobs, int p_max_blobs, int p_overload_frames, int p_extend_alarm_frames );
|
||||
|
@ -130,7 +151,14 @@ public:
|
|||
inline void ClearAlarm() { alarmed = false; }
|
||||
inline Coord GetAlarmCentre() const { return( alarm_centre ); }
|
||||
inline unsigned int Score() const { return( score ); }
|
||||
|
||||
inline std::string Text() const { return( text ); }
|
||||
void SetConfig( zConf zone_conf );
|
||||
inline bool IsPostProcEnabled() const { return post_proc_enabled; }
|
||||
inline bool IsNatDetIncluded() const { return include_nat_det; }
|
||||
inline bool IsNatDetReInitialized() const { return reinit_nat_det; }
|
||||
inline void StartPostProcessing() { post_proc_in_progress = true; }
|
||||
inline void StopPostProcessing() { post_proc_in_progress = false; }
|
||||
inline bool IsPostProcInProgress() { return post_proc_in_progress; }
|
||||
inline void ResetStats()
|
||||
{
|
||||
alarmed = false;
|
||||
|
@ -142,9 +170,10 @@ public:
|
|||
min_blob_size = 0;
|
||||
max_blob_size = 0;
|
||||
score = 0;
|
||||
text = "";
|
||||
}
|
||||
void RecordStats( const Event *event );
|
||||
bool CheckAlarms( const Image *delta_image );
|
||||
bool CheckAlarms( const Image *comp_image );
|
||||
bool DumpSettings( char *output, bool verbose );
|
||||
|
||||
static bool ParsePolygonString( const char *polygon_string, Polygon &polygon );
|
||||
|
@ -161,7 +190,15 @@ public:
|
|||
void SetExtendAlarmCount(int nOverCount);
|
||||
int GetExtendAlarmFrames();
|
||||
void SetScore(unsigned int nScore);
|
||||
void SetText(std::string sText);
|
||||
void SetAlarmImage(const Image* srcImage);
|
||||
void AssignRefImage( unsigned int p_width, unsigned int p_height, unsigned int p_colours, unsigned int p_subpixelorder, const uint8_t* new_buffer, const size_t buffer_size );
|
||||
void SetRefImage( const Image &srcImage);
|
||||
void BlendRefImage( const Image &srcImage, int transparency=12 );
|
||||
void SetDeltaImage( const Image &srcImage );
|
||||
void FillDeltaImage( Rgb colour );
|
||||
bool WriteRefImage( const char *filename, int quality_override=0 ) const;
|
||||
bool WriteDeltaImage( const char *filename, int quality_override=0 ) const;
|
||||
|
||||
inline const Image *getPgImage() const { return( pg_image ); }
|
||||
inline const Range *getRanges() const { return( ranges ); }
|
||||
|
|
Loading…
Reference in New Issue