From 2c09dbeeb9fd1d65bab1af93013762914416f378 Mon Sep 17 00:00:00 2001 From: stan Date: Tue, 5 Jun 2007 14:12:14 +0000 Subject: [PATCH] Bug 410 - Added in detection suspension if motion overloaded. git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@2132 e3e1d417-86f3-4887-817a-d78f3d33393f --- db/zm_create.sql.in | 14 ++++---- db/zm_update-1.22.3.sql | 6 ++++ src/zm_monitor.cpp | 10 +++--- src/zm_zone.cpp | 75 +++++++++++++++++++++++++++++++-------- src/zm_zone.h | 16 +++++---- web/zm_html_view_zone.php | 6 ++++ web/zm_lang_en_gb.php | 1 + 7 files changed, 97 insertions(+), 31 deletions(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index a5380cd90..d186fe2b3 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -453,6 +453,7 @@ CREATE TABLE `ZonePresets` ( `MaxBlobPixels` int(10) unsigned default NULL, `MinBlobs` smallint(5) unsigned default NULL, `MaxBlobs` smallint(5) unsigned default NULL, + `OverloadFrames` smallint(5) unsigned NOT NULL default '0', PRIMARY KEY (`Id`), UNIQUE KEY `UC_Id` (`Id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; @@ -485,6 +486,7 @@ CREATE TABLE `Zones` ( `MaxBlobPixels` int(10) unsigned default NULL, `MinBlobs` smallint(5) unsigned default NULL, `MaxBlobs` smallint(5) unsigned default NULL, + `OverloadFrames` smallint(5) unsigned NOT NULL default '0', PRIMARY KEY (`Id`), UNIQUE KEY `UC_Id` (`Id`), KEY `MonitorId` (`MonitorId`) @@ -571,12 +573,12 @@ INSERT INTO MonitorPresets VALUES ('','Gadspot IP, mpjpeg','Remote',NULL,NULL,NU -- -- Add some zone preset values -- -INSERT INTO ZonePresets VALUES (1,'Fast, low sensitivity','Active','Percent','AlarmedPixels',60,NULL,20,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -INSERT INTO ZonePresets VALUES (2,'Fast, medium sensitivity','Active','Percent','AlarmedPixels',40,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -INSERT INTO ZonePresets VALUES (3,'Fast, high sensitivity','Active','Percent','AlarmedPixels',20,NULL,5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -INSERT INTO ZonePresets VALUES (4,'Best, low sensitivity','Active','Percent','Blobs',60,NULL,36,NULL,7,7,24,NULL,20,NULL,1,NULL); -INSERT INTO ZonePresets VALUES (5,'Best, medium sensitivity','Active','Percent','Blobs',40,NULL,16,NULL,5,5,12,NULL,10,NULL,1,NULL); -INSERT INTO ZonePresets VALUES (6,'Best, high sensitivity','Active','Percent','Blobs',20,NULL,8,NULL,3,3,6,NULL,5,NULL,1,NULL); +INSERT INTO ZonePresets VALUES (1,'Fast, low sensitivity','Active','Percent','AlarmedPixels',60,NULL,20,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0); +INSERT INTO ZonePresets VALUES (2,'Fast, medium sensitivity','Active','Percent','AlarmedPixels',40,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0); +INSERT INTO ZonePresets VALUES (3,'Fast, high sensitivity','Active','Percent','AlarmedPixels',20,NULL,5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0); +INSERT INTO ZonePresets VALUES (4,'Best, low sensitivity','Active','Percent','Blobs',60,NULL,36,NULL,7,7,24,NULL,20,NULL,1,NULL,0); +INSERT INTO ZonePresets VALUES (5,'Best, medium sensitivity','Active','Percent','Blobs',40,NULL,16,NULL,5,5,12,NULL,10,NULL,1,NULL,0); +INSERT INTO ZonePresets VALUES (6,'Best, high sensitivity','Active','Percent','Blobs',20,NULL,8,NULL,3,3,6,NULL,5,NULL,1,NULL,0); -- -- Apply the initial configuration diff --git a/db/zm_update-1.22.3.sql b/db/zm_update-1.22.3.sql index 4fd4faa76..9b15cfb62 100644 --- a/db/zm_update-1.22.3.sql +++ b/db/zm_update-1.22.3.sql @@ -7,6 +7,12 @@ -- alter table States modify column Definition text; +-- +-- Add overload shutout to zones and presets +-- +alter table Zones add column OverloadFrames smallint(5) unsigned NOT NULL default '0' after MaxBlobs; +alter table ZonePresets add column OverloadFrames smallint(5) unsigned NOT NULL default '0' after MaxBlobs; + -- -- These are optional, but we might as well do it now -- diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 0b843c458..9ee711bbc 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1097,11 +1097,11 @@ bool Monitor::Analyse() { if ( state == IDLE || state == TAPE ) { - Info(( "Ended event" )); + Info(( "%s: %03d - Ending event %d", name, image_count, event->Id() )); } else { - Info(( "Force closed event" )); + Info(( "%s: %03d - Force closing event %d", name, image_count, event->Id() )); } closeEvent(); last_section_mod = 0; @@ -1162,6 +1162,8 @@ bool Monitor::Analyse() } shared_data->last_event = event->Id(); + Info(( "%s: %03d - Creating new event %d", name, image_count, event->Id() )); + for ( int i = 0; i < pre_event_count; i++ ) { timestamps[i] = image_buffer[pre_index].timestamp; @@ -1309,7 +1311,7 @@ bool Monitor::Analyse() int section_mod = timestamp->tv_sec%section_length; if ( section_mod < last_section_mod ) { - Info(( "Ended event" )); + Info(( "%s: %03d - Ending event %d", name, image_count, event->Id() )); closeEvent(); last_section_mod = 0; } @@ -1325,7 +1327,7 @@ bool Monitor::Analyse() { if ( event ) { - Info(( "Closed event" )); + Info(( "%s: %03d - Closing event %d", name, image_count, event->Id() )); closeEvent(); } shared_data->state = state = IDLE; diff --git a/src/zm_zone.cpp b/src/zm_zone.cpp index 35efc8d1c..6f777456c 100644 --- a/src/zm_zone.cpp +++ b/src/zm_zone.cpp @@ -23,7 +23,7 @@ #include "zm_image.h" #include "zm_monitor.h" -void Zone::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 ) +void Zone::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 ) { monitor = p_monitor; @@ -45,8 +45,9 @@ void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_ max_blob_pixels = p_max_blob_pixels; min_blobs = p_min_blobs; max_blobs = p_max_blobs; + overload_frames = p_overload_frames; - Debug( 1, ( "Initialised zone %d/%s - %d - %dx%d - Rgb:%06x, CM:%d, MnAT:%d, MxAT:%d, MnAP:%d, MxAP:%d, FB:%dx%d, MnFP:%d, MxFP:%d, MnBS:%d, MxBS:%d, MnB:%d, MxB:%d", id, label, type, polygon.Width(), polygon.Height(), alarm_rgb, check_method, min_pixel_threshold, max_pixel_threshold, min_alarm_pixels, max_alarm_pixels, filter_box.X(), filter_box.Y(), min_filter_pixels, max_filter_pixels, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs )); + Debug( 1, ( "Initialised zone %d/%s - %d - %dx%d - Rgb:%06x, CM:%d, MnAT:%d, MxAT:%d, MnAP:%d, MxAP:%d, FB:%dx%d, MnFP:%d, MxFP:%d, MnBS:%d, MxBS:%d, MnB:%d, MxB:%d, OF: %d", id, label, type, polygon.Width(), polygon.Height(), alarm_rgb, check_method, min_pixel_threshold, max_pixel_threshold, min_alarm_pixels, max_alarm_pixels, filter_box.X(), filter_box.Y(), min_filter_pixels, max_filter_pixels, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs, overload_frames )); alarmed = false; pixel_diff = 0; @@ -59,6 +60,8 @@ void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_ image = 0; score = 0; + overload_count = 0; + pg_image = new Image( monitor->Width(), monitor->Height(), 1 ); pg_image->Fill( 0xff, polygon ); pg_image->Outline( 0xff, polygon ); @@ -116,6 +119,14 @@ bool Zone::CheckAlarms( const Image *delta_image ) ResetStats(); + if ( overload_count ) + { + 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--; + return( false ); + } + delete image; // Get the difference image Image *diff_image = image = new Image( *delta_image ); @@ -139,6 +150,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) int hi_x; Debug( 4, ( "Checking alarms for zone %d/%s in lines %d -> %d", id, label, lo_y, hi_y )); + Debug( 5, ( "Checking for alarmed pixels" )); unsigned char *pdiff, *ppoly; // Create an upper margin @@ -212,10 +224,19 @@ bool Zone::CheckAlarms( const Image *delta_image ) diff_image->WriteJpeg( diag_path ); } - 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 ); - + 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) ) + { + overload_count = overload_frames; + return( false ); + } score = (100*alarm_pixels)/polygon.Area(); Debug( 5, ( "Current score is %d", score )); @@ -294,9 +315,19 @@ bool Zone::CheckAlarms( const Image *delta_image ) } Debug( 5, ( "Got %d filtered pixels, need %d -> %d", alarm_filter_pixels, min_filter_pixels, max_filter_pixels )); - 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 ); + 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) ) + { + overload_count = overload_frames; + return( false ); + } score = (100*alarm_filter_pixels)/(polygon.Area()); Debug( 5, ( "Current score is %d", score )); @@ -505,7 +536,10 @@ bool Zone::CheckAlarms( const Image *delta_image ) diff_image->WriteJpeg( diag_path ); } - if ( !alarm_blobs ) return( false ); + if ( !alarm_blobs ) + { + return( false ); + } alarm_blob_pixels = alarm_filter_pixels; Debug( 5, ( "Got %d raw blob pixels, %d raw blobs, need %d -> %d, %d -> %d", alarm_blob_pixels, alarm_blobs, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs )); @@ -562,9 +596,19 @@ bool Zone::CheckAlarms( const Image *delta_image ) } 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 )); - if ( !alarm_blobs ) return( false ); - if ( min_blobs && alarm_blobs < min_blobs ) return( false ); - if ( max_blobs && alarm_blobs > max_blobs ) return( false ); + if ( !alarm_blobs ) + { + return( false ); + } + if ( min_blobs && (alarm_blobs < min_blobs) ) + { + return( false ); + } + if ( max_blobs && (alarm_blobs > max_blobs) ) + { + overload_count = overload_frames; + return( false ); + } alarm_lo_x = polygon.HiX()+1; alarm_hi_x = polygon.LoX()-1; @@ -832,7 +876,7 @@ bool Zone::ParseZoneString( const char *zone_string, int &zone_id, int &colour, int Zone::Load( Monitor *monitor, Zone **&zones ) { static char sql[BUFSIZ]; - snprintf( sql, sizeof(sql), "select Id,Name,Type+0,Units,NumCoords,Coords,AlarmRGB,CheckMethod+0,MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,FilterX,FilterY,MinFilterPixels,MaxFilterPixels,MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs from Zones where MonitorId = %d order by Type, Id", monitor->Id() ); + snprintf( sql, sizeof(sql), "select Id,Name,Type+0,Units,NumCoords,Coords,AlarmRGB,CheckMethod+0,MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,FilterX,FilterY,MinFilterPixels,MaxFilterPixels,MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,OverloadFrames from Zones where MonitorId = %d order by Type, Id", monitor->Id() ); if ( mysql_query( &dbconn, sql ) ) { Error(( "Can't run query: %s", mysql_error( &dbconn ) )); @@ -873,6 +917,7 @@ int Zone::Load( Monitor *monitor, Zone **&zones ) int MaxBlobPixels = dbrow[col]?atoi(dbrow[col]):0; col++; int MinBlobs = dbrow[col]?atoi(dbrow[col]):0; col++; int MaxBlobs = dbrow[col]?atoi(dbrow[col]):0; col++; + int OverloadFrames = dbrow[col]?atoi(dbrow[col]):0; col++; Debug( 5, ( "Parsing polygon %s", Coords )); Polygon polygon; @@ -898,7 +943,7 @@ int Zone::Load( Monitor *monitor, Zone **&zones ) } else { - zones[i] = new Zone( monitor, Id, Name, (Zone::ZoneType)Type, polygon, AlarmRGB, (Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold, MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ), MinFilterPixels, MaxFilterPixels, MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs ); + zones[i] = new Zone( monitor, Id, Name, (Zone::ZoneType)Type, polygon, AlarmRGB, (Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold, MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ), MinFilterPixels, MaxFilterPixels, MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs, OverloadFrames ); } } if ( mysql_errno( &dbconn ) ) diff --git a/src/zm_zone.h b/src/zm_zone.h index eb54a5b67..0d73d6971 100644 --- a/src/zm_zone.h +++ b/src/zm_zone.h @@ -72,6 +72,8 @@ protected: int min_blobs; int max_blobs; + int overload_frames; + // Outputs/Statistics bool alarmed; int pixel_diff; @@ -88,21 +90,23 @@ protected: Range *ranges; Image *image; + int overload_count; + 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 ); + 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 ); public: - Zone( 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=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0 ) + Zone( 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=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0, int p_overload_frames=0 ) { - Setup( p_monitor, p_id, p_label, p_type, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs ); + Setup( p_monitor, p_id, p_label, p_type, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs, p_overload_frames ); } - Zone( Monitor *p_monitor, int p_id, const char *p_label, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0 ) + Zone( Monitor *p_monitor, int p_id, const char *p_label, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0, int p_overload_frames=0 ) { - Setup( p_monitor, p_id, p_label, Zone::ACTIVE, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs ); + Setup( p_monitor, p_id, p_label, Zone::ACTIVE, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs, p_overload_frames ); } Zone( Monitor *p_monitor, int p_id, const char *p_label, const Polygon &p_polygon ) { - Setup( p_monitor, p_id, p_label, Zone::INACTIVE, p_polygon, RGB_BLACK, (Zone::CheckMethod)0, 0, 0, 0, 0, Coord( 0, 0 ), 0, 0, 0, 0, 0, 0 ); + Setup( p_monitor, p_id, p_label, Zone::INACTIVE, p_polygon, RGB_BLACK, (Zone::CheckMethod)0, 0, 0, 0, 0, Coord( 0, 0 ), 0, 0, 0, 0, 0, 0, 0 ); } public: diff --git a/web/zm_html_view_zone.php b/web/zm_html_view_zone.php index 109d14dae..0487db6e2 100644 --- a/web/zm_html_view_zone.php +++ b/web/zm_html_view_zone.php @@ -277,6 +277,7 @@ function applyZoneType() form.elements['new_zone[MaxBlobPixels]'].disabled = true; form.elements['new_zone[MinBlobs]'].disabled = true; form.elements['new_zone[MaxBlobs]'].disabled = true; + form.elements['new_zone[OverloadFrames]'].disabled = true; } else if ( form.elements['new_zone[Type]'].value == 'Preclusive' ) { @@ -289,6 +290,7 @@ function applyZoneType() form.elements['new_zone[MaxPixelThreshold]'].disabled = false; form.elements['new_zone[MinAlarmPixels]'].disabled = false; form.elements['new_zone[MaxAlarmPixels]'].disabled = false; + form.elements['new_zone[OverloadFrames]'].disabled = false; applyCheckMethod(); } else @@ -302,6 +304,7 @@ function applyZoneType() form.elements['new_zone[MaxPixelThreshold]'].disabled = false; form.elements['new_zone[MinAlarmPixels]'].disabled = false; form.elements['new_zone[MaxAlarmPixels]'].disabled = false; + form.elements['new_zone[OverloadFrames]'].disabled = false; applyCheckMethod(); } } @@ -371,6 +374,7 @@ foreach ( $presets as $preset ) form.elements['new_zone[MaxBlobPixels]'].value = ''; form.elements['new_zone[MinBlobs]'].value = ''; form.elements['new_zone[MaxBlobs]'].value = ''; + form.elements['new_zone[OverloadFrames]'].value = ''; break; } + +   diff --git a/web/zm_lang_en_gb.php b/web/zm_lang_en_gb.php index 26fac73cb..434404629 100644 --- a/web/zm_lang_en_gb.php +++ b/web/zm_lang_en_gb.php @@ -642,6 +642,7 @@ $zmSlangZoneMinMaxBlobArea = 'Min/Max Blob Area'; $zmSlangZoneMinMaxBlobs = 'Min/Max Blobs'; $zmSlangZoneMinMaxFiltArea = 'Min/Max Filtered Area'; $zmSlangZoneMinMaxPixelThres = 'Min/Max Pixel Threshold (0-255)'; +$zmSlangZoneOverloadFrames = 'Overload Frame Ignore Count'; $zmSlangZones = 'Zones'; $zmSlangZone = 'Zone'; $zmSlangZoomIn = 'Zoom In';