diff --git a/src/zm_event.cpp b/src/zm_event.cpp index c43f394e5..9284cf139 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -225,7 +225,7 @@ void Event::AddFrames( int n_frames, struct timeval **timestamps, const Image ** } } -void Event::AddFrame( struct timeval timestamp, const Image *image, const Image *alarm_image, unsigned int score ) +void Event::AddFrame( struct timeval timestamp, const Image *image, unsigned int score, const Image *alarm_image ) { frames++; @@ -240,27 +240,30 @@ void Event::AddFrame( struct timeval timestamp, const Image *image, const Image Debug( 1, ( "Adding frame %d to DB", frames )); static char sql[BUFSIZ]; - sprintf( sql, "insert into Frames ( EventId, FrameId, AlarmFrame, ImagePath, Delta, Score ) values ( %d, %d, %d, '%s', %s%ld.%02ld, %d )", id, frames, alarm_image!=0, event_file, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, score ); + sprintf( sql, "insert into Frames ( EventId, FrameId, AlarmFrame, ImagePath, Delta, Score ) values ( %d, %d, %d, '%s', %s%ld.%02ld, %d )", id, frames, score>0, event_file, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, score ); if ( mysql_query( &dbconn, sql ) ) { Error(( "Can't insert frame: %s", mysql_error( &dbconn ) )); exit( mysql_errno( &dbconn ) ); } - if ( alarm_image ) + if ( score ) { end_time = timestamp; alarm_frames++; - sprintf( event_file, "%s/analyse-%03d.jpg", path, frames ); - - Debug( 1, ( "Writing analysis frame %d", frames )); - WriteFrameImage( alarm_image, event_file, true ); - tot_score += score; if ( score > max_score ) max_score = score; + + if ( alarm_image ) + { + sprintf( event_file, "%s/analyse-%03d.jpg", path, frames ); + + Debug( 1, ( "Writing analysis frame %d", frames )); + WriteFrameImage( alarm_image, event_file, true ); + } } } diff --git a/src/zm_event.h b/src/zm_event.h index e921552a7..056e04987 100644 --- a/src/zm_event.h +++ b/src/zm_event.h @@ -81,7 +81,7 @@ public: bool WriteFrameImage( const Image *image, const char *event_file, bool alarm_frame=false ); void AddFrames( int n_frames, struct timeval **timestamps, const Image **images ); - void AddFrame( struct timeval timestamp, const Image *image, const Image *alarm_frame=NULL, unsigned int score=0 ); + void AddFrame( struct timeval timestamp, const Image *image, unsigned int score=0, const Image *alarm_frame=NULL ); static void StreamEvent( const char *path, int event_id, int rate=1, int scale=1, FILE *fd=stdout ); }; diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 83279cda3..ee6edc545 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -638,11 +638,9 @@ bool Monitor::Analyse() pre_index = (pre_index+1)%image_buffer_count; } event->AddFrames( pre_event_count, timestamps, images ); - //event->AddFrame( now, &image ); } shared_data->state = state = TAPE; } - //last_alarm_count = image_count; } if ( score ) { @@ -664,7 +662,6 @@ bool Monitor::Analyse() pre_index = (pre_index+1)%image_buffer_count; } event->AddFrames( pre_event_count, timestamps, images ); - //event->AddFrame( now, &image ); } } shared_data->state = state = ALARM; @@ -699,19 +696,26 @@ bool Monitor::Analyse() { if ( state == ALARM ) { - Image alarm_image( *image ); - for( int i = 0; i < n_zones; i++ ) + if ( (bool)config.Item( ZM_CREATE_ANALYSIS_IMAGES ) ) { - if ( zones[i]->Alarmed() ) + Image alarm_image( *image ); + for( int i = 0; i < n_zones; i++ ) { - alarm_image.Overlay( zones[i]->AlarmImage() ); - if ( record_event_stats ) + if ( zones[i]->Alarmed() ) { - zones[i]->RecordStats( event ); + alarm_image.Overlay( zones[i]->AlarmImage() ); + if ( record_event_stats ) + { + zones[i]->RecordStats( event ); + } } } + event->AddFrame( *timestamp, image, score, &alarm_image ); + } + else + { + event->AddFrame( *timestamp, image, score ); } - event->AddFrame( *timestamp, image, &alarm_image, score ); } else if ( state == ALERT ) { @@ -1208,7 +1212,7 @@ unsigned int Monitor::Compare( const Image &image ) } else { - // Find all alarm pixels in exclusion zones + // Find all alarm pixels in exclusive zones for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) { Zone *zone = zones[n_zone]; diff --git a/src/zm_zone.cpp b/src/zm_zone.cpp index e6b966e7d..d7b069e7f 100644 --- a/src/zm_zone.cpp +++ b/src/zm_zone.cpp @@ -104,8 +104,6 @@ bool Zone::CheckAlarms( const Image *delta_image ) } } - //diff_image->WriteJpeg( "diff1.jpg" ); - if ( !alarm_pixels ) return( false ); if ( min_alarm_pixels && alarm_pixels < min_alarm_pixels ) return( false ); if ( max_alarm_pixels && alarm_pixels > max_alarm_pixels ) return( false ); @@ -162,8 +160,6 @@ bool Zone::CheckAlarms( const Image *delta_image ) } } - //diff_image->WriteJpeg( "diff2.jpg" ); - if ( !alarm_filter_pixels ) return( false ); if ( min_filter_pixels && alarm_filter_pixels < min_filter_pixels ) return( false ); if ( max_filter_pixels && alarm_filter_pixels > max_filter_pixels ) return( false ); @@ -301,7 +297,6 @@ bool Zone::CheckAlarms( const Image *delta_image ) } } - //diff_image->WriteJpeg( "diff3.jpg" ); if ( !alarm_blobs ) return( false ); alarm_blob_pixels = alarm_filter_pixels; @@ -381,11 +376,14 @@ bool Zone::CheckAlarms( const Image *delta_image ) if ( alarm_blobs ) { alarm = true; - //Image *high_image = image = diff_image->HighlightEdges( alarm_rgb, &limits ); - image = diff_image->HighlightEdges( alarm_rgb, &limits ); - delete diff_image; - //high_image->WriteJpeg( "diff4.jpg" ); + if ( (type < PRECLUSIVE) && (bool)config.Item( ZM_CREATE_ANALYSIS_IMAGES ) ) + { + image = diff_image->HighlightEdges( alarm_rgb, &limits ); + + // Only need to delete this when 'image' becomes detached and points somewhere else + delete diff_image; + } Info(( "%s: Alarm Pixels: %d, Filter Pixels: %d, Blob Pixels: %d, Blobs: %d, Score: %d", Label(), alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, score )); } diff --git a/zmconfig.pl.in b/zmconfig.pl.in index 1f7bd1f96..b07e65e17 100755 --- a/zmconfig.pl.in +++ b/zmconfig.pl.in @@ -778,6 +778,14 @@ my @options = type => $types{boolean}, category => 'system', }, + { + name => "ZM_CREATE_ANALYSIS_IMAGES", + default => "yes", + description => "Whether to create analysed alarm images with motion outlined", + help => "By default during an alarm ZoneMinder records both the raw captured image and one that has been analysed and had areas where motion was detected outlined. This can be very useful during zone configuration or in analysing why events occured. However it also incurs some overhead and in a stable system may no longer be necessary. This parameter allows you to switch the generation of these images off.", + type => $types{boolean}, + category => 'system', + }, { name => "ZM_WEB_REFRESH_METHOD", default => "javascript",