2003-03-26 20:03:37 +08:00
//
// ZoneMinder Zone Class Implementation, $Date$, $Revision$
2005-02-24 22:40:14 +08:00
// Copyright (C) 2003, 2004, 2005 Philip Coombes
2003-03-26 20:03:37 +08:00
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
# include "zm.h"
# include "zm_db.h"
# include "zm_zone.h"
# include "zm_image.h"
# include "zm_monitor.h"
2004-02-16 04:02:41 +08:00
void Zone : : Setup ( Monitor * p_monitor , int p_id , const char * p_label , ZoneType p_type , const Box & p_limits , 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 )
2003-03-26 20:03:37 +08:00
{
monitor = p_monitor ;
id = p_id ;
label = new char [ strlen ( p_label ) + 1 ] ;
strcpy ( label , p_label ) ;
type = p_type ;
limits = p_limits ;
alarm_rgb = p_alarm_rgb ;
2004-02-16 04:02:41 +08:00
check_method = p_check_method ;
2004-01-27 20:27:22 +08:00
min_pixel_threshold = p_min_pixel_threshold ;
max_pixel_threshold = p_max_pixel_threshold ;
2003-03-26 20:03:37 +08:00
min_alarm_pixels = p_min_alarm_pixels ;
max_alarm_pixels = p_max_alarm_pixels ;
filter_box = p_filter_box ;
min_filter_pixels = p_min_filter_pixels ;
max_filter_pixels = p_max_filter_pixels ;
min_blob_pixels = p_min_blob_pixels ;
max_blob_pixels = p_max_blob_pixels ;
min_blobs = p_min_blobs ;
max_blobs = p_max_blobs ;
2004-03-17 18:28:07 +08:00
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 , limits . Width ( ) , limits . 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 ) ) ;
2003-03-26 20:03:37 +08:00
alarmed = false ;
alarm_pixels = 0 ;
alarm_filter_pixels = 0 ;
alarm_blob_pixels = 0 ;
alarm_blobs = 0 ;
2003-04-11 23:42:24 +08:00
min_blob_size = 0 ;
max_blob_size = 0 ;
2003-03-26 20:03:37 +08:00
image = 0 ;
score = 0 ;
}
Zone : : ~ Zone ( )
{
delete [ ] label ;
delete image ;
}
void Zone : : RecordStats ( const Event * event )
{
2003-07-04 04:39:47 +08:00
static char sql [ BUFSIZ ] ;
2004-04-20 00:02:17 +08:00
snprintf ( sql , sizeof ( sql ) , " insert into Stats set MonitorId=%d, ZoneId=%d, EventId=%d, FrameId=%d, AlarmPixels=%d, FilterPixels=%d, BlobPixels=%d, Blobs=%d, MinBlobSize=%d, MaxBlobSize=%d, MinX=%d, MinY=%d, MaxX=%d, MaxY=%d, Score=%d " , monitor - > Id ( ) , id , event - > Id ( ) , event - > Frames ( ) + 1 , alarm_pixels , alarm_filter_pixels , alarm_blob_pixels , alarm_blobs , min_blob_size , max_blob_size , alarm_box . LoX ( ) , alarm_box . LoY ( ) , alarm_box . HiX ( ) , alarm_box . HiY ( ) , score ) ;
2003-03-26 20:03:37 +08:00
if ( mysql_query ( & dbconn , sql ) )
{
2003-04-17 19:36:08 +08:00
Error ( ( " Can't insert event stats: %s " , mysql_error ( & dbconn ) ) ) ;
2003-03-26 20:03:37 +08:00
exit ( mysql_errno ( & dbconn ) ) ;
}
}
bool Zone : : CheckAlarms ( const Image * delta_image )
{
bool alarm = false ;
ResetStats ( ) ;
delete image ;
2004-02-16 04:02:41 +08:00
// Get the difference image
2003-03-26 20:03:37 +08:00
Image * diff_image = image = new Image ( * delta_image ) ;
2004-02-16 04:02:41 +08:00
int alarm_lo_x = 0 ;
int alarm_hi_x = 0 ;
int alarm_lo_y = 0 ;
int alarm_hi_y = 0 ;
2003-03-26 20:03:37 +08:00
2005-02-24 18:43:29 +08:00
int alarm_mid_x = - 1 ;
int alarm_mid_y = - 1 ;
2003-03-26 20:03:37 +08:00
int lo_x = limits . Lo ( ) . X ( ) ;
int lo_y = limits . Lo ( ) . Y ( ) ;
int hi_x = limits . Hi ( ) . X ( ) ;
int hi_y = limits . Hi ( ) . Y ( ) ;
2004-02-16 04:02:41 +08:00
2004-02-16 07:16:35 +08:00
unsigned char * pdiff ;
2003-03-26 20:03:37 +08:00
for ( int y = lo_y ; y < = hi_y ; y + + )
{
2004-02-16 07:16:35 +08:00
pdiff = diff_image - > Buffer ( lo_x , y ) ;
2003-03-26 20:03:37 +08:00
for ( int x = lo_x ; x < = hi_x ; x + + , pdiff + + )
{
2004-02-16 07:16:35 +08:00
if ( ( * pdiff > min_pixel_threshold ) & & ( ! max_pixel_threshold | | ( * pdiff < max_pixel_threshold ) ) )
2003-03-26 20:03:37 +08:00
{
* pdiff = WHITE ;
alarm_pixels + + ;
}
2004-02-16 04:02:41 +08:00
else
{
* pdiff = BLACK ;
}
2003-03-26 20:03:37 +08:00
}
}
2005-05-16 17:27:06 +08:00
if ( config . record_diag_images )
2004-01-28 01:03:45 +08:00
{
static char diag_path [ PATH_MAX ] = " " ;
if ( ! diag_path [ 0 ] )
{
2005-05-16 17:27:06 +08:00
snprintf ( diag_path , sizeof ( diag_path ) , " %s/%s/diag-%d-%d.jpg " , config . dir_events , monitor - > Name ( ) , id , 1 ) ;
2004-01-28 01:03:45 +08:00
}
diff_image - > WriteJpeg ( diag_path ) ;
}
2003-03-26 20:03:37 +08:00
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 ) ;
2004-02-16 04:02:41 +08:00
score = ( 100 * alarm_pixels ) / ( limits . Size ( ) . X ( ) * limits . Size ( ) . Y ( ) ) ;
2003-03-26 20:03:37 +08:00
2004-02-16 04:02:41 +08:00
if ( check_method > = FILTERED_PIXELS )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
int bx = filter_box . X ( ) ;
int by = filter_box . Y ( ) ;
int bx1 = bx - 1 ;
int by1 = by - 1 ;
2004-01-28 01:03:45 +08:00
2004-02-16 04:02:41 +08:00
if ( bx > 1 | | by > 1 )
{
// Now remove any pixels smaller than our filter size
unsigned char * pdiff ;
unsigned char * cpdiff ;
int ldx , hdx , ldy , hdy ;
bool block ;
for ( int y = lo_y ; y < = hi_y ; y + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
pdiff = diff_image - > Buffer ( lo_x , y ) ;
for ( int x = lo_x ; x < = hi_x ; x + + , pdiff + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
if ( * pdiff = = WHITE )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
// Check participation in an X block
ldx = ( x > = ( lo_x + bx1 ) ) ? - bx1 : lo_x - x ;
hdx = ( x < = ( hi_x - bx1 ) ) ? 0 : ( ( hi_x - x ) - bx1 ) ;
ldy = ( y > = ( lo_y + by1 ) ) ? - by1 : lo_y - y ;
hdy = ( y < = ( hi_y - by1 ) ) ? 0 : ( ( hi_y - y ) - by1 ) ;
block = false ;
for ( int dy = ldy ; ! block & & dy < = hdy ; dy + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
for ( int dx = ldx ; ! block & & dx < = hdx ; dx + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
block = true ;
for ( int dy2 = 0 ; block & & dy2 < by ; dy2 + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
for ( int dx2 = 0 ; block & & dx2 < bx ; dx2 + + )
2004-01-28 01:03:45 +08:00
{
2004-02-16 04:02:41 +08:00
cpdiff = diff_image - > Buffer ( x + dx + dx2 , y + dy + dy2 ) ;
if ( ! * cpdiff )
{
block = false ;
}
2004-01-28 01:03:45 +08:00
}
2003-03-26 20:03:37 +08:00
}
}
}
2004-02-16 04:02:41 +08:00
if ( ! block )
{
* pdiff = BLACK ;
continue ;
}
alarm_filter_pixels + + ;
2003-03-26 20:03:37 +08:00
}
}
}
}
2004-08-11 23:20:09 +08:00
else
{
alarm_filter_pixels = alarm_pixels ;
}
2005-05-16 17:27:06 +08:00
if ( config . record_diag_images )
2004-01-28 01:03:45 +08:00
{
2004-02-16 03:53:10 +08:00
static char diag_path [ PATH_MAX ] = " " ;
if ( ! diag_path [ 0 ] )
{
2005-05-16 17:27:06 +08:00
snprintf ( diag_path , sizeof ( diag_path ) , " %s/%d/diag-%d-%d.jpg " , config . dir_events , monitor - > Id ( ) , id , 2 ) ;
2004-02-16 03:53:10 +08:00
}
diff_image - > WriteJpeg ( diag_path ) ;
2004-01-28 01:03:45 +08:00
}
2003-03-26 20:03:37 +08:00
2004-02-16 03:53:10 +08:00
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 ) ;
2003-03-26 20:03:37 +08:00
2004-02-16 04:02:41 +08:00
score = ( 100 * alarm_filter_pixels ) / ( limits . Size ( ) . X ( ) * limits . Size ( ) . Y ( ) ) ;
2003-03-26 20:03:37 +08:00
2004-02-16 04:02:41 +08:00
if ( check_method > = BLOBS )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
typedef struct { unsigned char tag ; int count ; int lo_x ; int hi_x ; int lo_y ; int hi_y ; } BlobStats ;
BlobStats blob_stats [ 256 ] ;
memset ( blob_stats , 0 , sizeof ( BlobStats ) * 256 ) ;
unsigned char * pdiff , * spdiff ;
2005-11-03 18:48:50 +08:00
int last_x , last_y ;
2004-02-16 04:02:41 +08:00
BlobStats * bsx , * bsy ;
BlobStats * bsm , * bss ;
2005-11-03 18:48:50 +08:00
int diff_width = diff_image - > Width ( ) ;
2004-02-16 04:02:41 +08:00
for ( int y = lo_y ; y < = hi_y ; y + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
pdiff = diff_image - > Buffer ( lo_x , y ) ;
for ( int x = lo_x ; x < = hi_x ; x + + , pdiff + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
if ( * pdiff = = WHITE )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
//printf( "Got white pixel at %d,%d (%x)\n", x, y, pdiff );
2005-11-03 18:48:50 +08:00
last_x = x > lo_x ? * ( pdiff - 1 ) : 0 ;
last_y = y > lo_y ? * ( pdiff - diff_width ) : 0 ;
if ( last_x )
2003-03-26 20:03:37 +08:00
{
2005-11-03 18:48:50 +08:00
//printf( "Left neighbour is %d\n", last_x );
bsx = & blob_stats [ last_x ] ;
if ( last_y )
2004-02-16 04:02:41 +08:00
{
2005-11-03 18:48:50 +08:00
//printf( "Top neighbour is %d\n", last_y );
bsy = & blob_stats [ last_y ] ;
if ( last_x = = last_y )
2004-02-16 04:02:41 +08:00
{
2005-11-03 18:48:50 +08:00
//printf( "Matching neighbours, setting to %d\n", last_x );
2004-02-16 04:02:41 +08:00
// Add to the blob from the x side (either side really)
2005-11-03 18:48:50 +08:00
* pdiff = last_x ;
2004-02-16 04:02:41 +08:00
bsx - > count + + ;
if ( x > bsx - > hi_x ) bsx - > hi_x = x ;
if ( y > bsx - > hi_y ) bsx - > hi_y = y ;
}
else
{
// Aggregate blobs
bsm = bsx - > count > = bsy - > count ? bsx : bsy ;
bss = bsm = = bsx ? bsy : bsx ;
//printf( "Different neighbours, setting pixels of %d to %d\n", bss->tag, bsm->tag );
// Now change all those pixels to the other setting
for ( int sy = bss - > lo_y ; sy < = bss - > hi_y ; sy + + )
{
spdiff = diff_image - > Buffer ( bss - > lo_x , sy ) ;
for ( int sx = bss - > lo_x ; sx < = bss - > hi_x ; sx + + , spdiff + + )
{
//printf( "Pixel at %d,%d (%x) is %d", sx, sy, spdiff, *spdiff );
if ( * spdiff = = bss - > tag )
{
//printf( ", setting" );
* spdiff = bsm - > tag ;
}
//printf( "\n" );
}
}
* pdiff = bsm - > tag ;
// Merge the slave blob into the master
bsm - > count + = bss - > count + 1 ;
if ( x > bsm - > hi_x ) bsm - > hi_x = x ;
if ( y > bsm - > hi_y ) bsm - > hi_y = y ;
if ( bss - > lo_x < bsm - > lo_x ) bsm - > lo_x = bss - > lo_x ;
if ( bss - > lo_y < bsm - > lo_y ) bsm - > lo_y = bss - > lo_y ;
if ( bss - > hi_x > bsm - > hi_x ) bsm - > hi_x = bss - > hi_x ;
if ( bss - > hi_y > bsm - > hi_y ) bsm - > hi_y = bss - > hi_y ;
2004-05-06 00:22:37 +08:00
alarm_blobs - - ;
Debug ( 2 , ( " Merging blob %d with %d, %d current blobs " , bss - > tag , bsm - > tag , alarm_blobs ) ) ;
2004-02-16 04:02:41 +08:00
// Clear out the old blob
bss - > tag = 0 ;
bss - > count = 0 ;
bss - > lo_x = 0 ;
bss - > lo_y = 0 ;
bss - > hi_x = 0 ;
bss - > hi_y = 0 ;
}
}
else
{
2005-11-03 18:48:50 +08:00
//printf( "Setting to left neighbour %d\n", last_x );
2004-02-16 04:02:41 +08:00
// Add to the blob from the x side
2005-11-03 18:48:50 +08:00
* pdiff = last_x ;
2004-02-16 04:02:41 +08:00
bsx - > count + + ;
if ( x > bsx - > hi_x ) bsx - > hi_x = x ;
if ( y > bsx - > hi_y ) bsx - > hi_y = y ;
}
2003-03-26 20:03:37 +08:00
}
else
{
2005-11-03 18:48:50 +08:00
if ( last_y )
2004-02-16 04:02:41 +08:00
{
2005-11-03 18:48:50 +08:00
//printf( "Setting to top neighbour %d\n", last_y );
2004-02-16 04:02:41 +08:00
// Add to the blob from the y side
2005-11-03 18:48:50 +08:00
BlobStats * bsy = & blob_stats [ last_y ] ;
2003-03-26 20:03:37 +08:00
2005-11-03 18:48:50 +08:00
* pdiff = last_y ;
2004-02-16 04:02:41 +08:00
bsy - > count + + ;
if ( x > bsy - > hi_x ) bsy - > hi_x = x ;
if ( y > bsy - > hi_y ) bsy - > hi_y = y ;
}
else
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
// Create a new blob
2005-11-03 18:48:50 +08:00
int i ;
for ( i = ( WHITE - 1 ) ; i > 0 ; i - - )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
BlobStats * bs = & blob_stats [ i ] ;
if ( ! bs - > count )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
//printf( "Creating new blob %d\n", i );
* pdiff = i ;
bs - > tag = i ;
bs - > count + + ;
bs - > lo_x = bs - > hi_x = x ;
bs - > lo_y = bs - > hi_y = y ;
alarm_blobs + + ;
2004-05-06 00:22:37 +08:00
Debug ( 2 , ( " Created blob %d, %d current blobs " , bs - > tag , alarm_blobs ) ) ;
2004-02-16 04:02:41 +08:00
break ;
2003-03-26 20:03:37 +08:00
}
}
2005-11-03 18:48:50 +08:00
if ( i = = 0 )
{
i = 1 ;
Warning ( ( " Max blob count reached. Unable to allocate new blob so extending last one. " ) ) ;
BlobStats * bs = & blob_stats [ i ] ;
* pdiff = i ;
if ( x > bs - > hi_x ) bs - > hi_x = x ;
if ( y > bs - > hi_y ) bs - > hi_y = y ;
}
2003-03-26 20:03:37 +08:00
}
}
}
}
2004-02-16 04:02:41 +08:00
}
2005-05-16 17:27:06 +08:00
if ( config . record_diag_images )
2004-02-16 04:02:41 +08:00
{
static char diag_path [ PATH_MAX ] = " " ;
if ( ! diag_path [ 0 ] )
2003-03-26 20:03:37 +08:00
{
2005-05-16 17:27:06 +08:00
snprintf ( diag_path , sizeof ( diag_path ) , " %s/%d/diag-%d-%d.jpg " , config . dir_events , monitor - > Id ( ) , id , 3 ) ;
2004-02-16 04:02:41 +08:00
}
diff_image - > WriteJpeg ( diag_path ) ;
}
2003-03-26 20:03:37 +08:00
2004-02-16 04:02:41 +08:00
if ( ! alarm_blobs ) return ( false ) ;
alarm_blob_pixels = alarm_filter_pixels ;
2003-03-26 20:03:37 +08:00
2004-02-16 04:02:41 +08:00
// Now eliminate blobs under the threshold
for ( int i = 1 ; i < WHITE ; i + + )
{
BlobStats * bs = & blob_stats [ i ] ;
if ( bs - > count & & ( ( min_blob_pixels & & bs - > count < min_blob_pixels ) | | ( max_blob_pixels & & bs - > count > max_blob_pixels ) ) )
{
for ( int sy = bs - > lo_y ; sy < = bs - > hi_y ; sy + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
unsigned char * spdiff = diff_image - > Buffer ( bs - > lo_x , sy ) ;
for ( int sx = bs - > lo_x ; sx < = bs - > hi_x ; sx + + , spdiff + + )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
if ( * spdiff = = bs - > tag )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
* spdiff = BLACK ;
2003-03-26 20:03:37 +08:00
}
}
}
2004-02-16 04:02:41 +08:00
alarm_blobs - - ;
alarm_blob_pixels - = bs - > count ;
2004-05-06 00:22:37 +08:00
Debug ( 2 , ( " Eliminated blob %d, %d pixels (%d,%d - %d,%d), %d current blobs " , i , bs - > count , bs - > lo_x , bs - > lo_y , bs - > hi_x , bs - > hi_y , alarm_blobs ) ) ;
2004-02-16 04:02:41 +08:00
bs - > tag = 0 ;
bs - > count = 0 ;
bs - > lo_x = 0 ;
bs - > lo_y = 0 ;
bs - > hi_x = 0 ;
bs - > hi_y = 0 ;
2003-03-26 20:03:37 +08:00
}
2004-02-16 04:02:41 +08:00
else
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
if ( bs - > count )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
if ( ! min_blob_size | | bs - > count < min_blob_size ) min_blob_size = bs - > count ;
if ( ! max_blob_size | | bs - > count > max_blob_size ) max_blob_size = bs - > count ;
2003-03-26 20:03:37 +08:00
}
}
}
2005-05-16 17:27:06 +08:00
if ( config . record_diag_images )
2003-03-26 20:03:37 +08:00
{
2004-02-16 04:02:41 +08:00
static char diag_path [ PATH_MAX ] = " " ;
if ( ! diag_path [ 0 ] )
{
2005-05-16 17:27:06 +08:00
snprintf ( diag_path , sizeof ( diag_path ) , " %s/%d/diag-%d-%d.jpg " , config . dir_events , monitor - > Id ( ) , id , 4 ) ;
2004-02-16 04:02:41 +08:00
}
diff_image - > WriteJpeg ( diag_path ) ;
2003-03-26 20:03:37 +08:00
}
2004-02-16 04:02:41 +08:00
if ( ! alarm_blobs ) return ( false ) ;
if ( min_blobs & & alarm_blobs < min_blobs ) return ( false ) ;
if ( max_blobs & & alarm_blobs > max_blobs ) return ( false ) ;
2003-03-26 20:03:37 +08:00
2004-02-16 04:02:41 +08:00
alarm_lo_x = hi_x + 1 ;
alarm_hi_x = lo_x - 1 ;
alarm_lo_y = hi_y + 1 ;
alarm_hi_y = lo_y - 1 ;
for ( int i = 1 ; i < WHITE ; i + + )
{
BlobStats * bs = & blob_stats [ i ] ;
if ( bs - > count )
{
2005-02-24 18:43:29 +08:00
if ( bs - > count = = max_blob_size )
{
//if ( monitor->followMotion() )
if ( true )
{
unsigned long x_total = 0 ;
unsigned long y_total = 0 ;
for ( int sy = bs - > lo_y ; sy < = bs - > hi_y ; sy + + )
{
unsigned char * spdiff = diff_image - > Buffer ( bs - > lo_x , sy ) ;
for ( int sx = bs - > lo_x ; sx < = bs - > hi_x ; sx + + , spdiff + + )
{
if ( * spdiff = = bs - > tag )
{
x_total + = sx ;
y_total + = sy ;
}
}
}
alarm_mid_x = int ( round ( x_total / bs - > count ) ) ;
alarm_mid_y = int ( round ( y_total / bs - > count ) ) ;
}
}
2004-02-16 04:02:41 +08:00
if ( alarm_lo_x > bs - > lo_x ) alarm_lo_x = bs - > lo_x ;
if ( alarm_lo_y > bs - > lo_y ) alarm_lo_y = bs - > lo_y ;
if ( alarm_hi_x < bs - > hi_x ) alarm_hi_x = bs - > hi_x ;
if ( alarm_hi_y < bs - > hi_y ) alarm_hi_y = bs - > hi_y ;
}
}
score = ( ( 100 * alarm_blob_pixels ) / int ( sqrt ( ( double ) alarm_blobs ) ) ) / ( limits . Size ( ) . X ( ) * limits . Size ( ) . Y ( ) ) ;
2003-03-26 20:03:37 +08:00
}
}
if ( type = = INCLUSIVE )
{
score / = 2 ;
}
else if ( type = = EXCLUSIVE )
{
score * = 2 ;
}
// Now outline the changed region
2004-02-16 04:02:41 +08:00
if ( score )
2003-03-26 20:03:37 +08:00
{
alarm = true ;
2004-02-16 04:02:41 +08:00
alarm_box = Box ( Coord ( alarm_lo_x , alarm_lo_y ) , Coord ( alarm_hi_x , alarm_hi_y ) ) ;
2005-02-24 18:43:29 +08:00
//if ( monitor->followMotion() )
if ( true )
{
alarm_centre = Coord ( alarm_mid_x , alarm_mid_y ) ;
}
else
{
alarm_centre = alarm_box . Centre ( ) ;
}
2005-05-16 17:27:06 +08:00
if ( ( type < PRECLUSIVE ) & & check_method > = BLOBS & & config . create_analysis_images )
2003-11-21 18:38:41 +08:00
{
image = diff_image - > HighlightEdges ( alarm_rgb , & limits ) ;
// Only need to delete this when 'image' becomes detached and points somewhere else
delete diff_image ;
}
2004-03-30 19:05:47 +08:00
else
{
delete image ;
image = 0 ;
}
2003-03-26 20:03:37 +08:00
2004-02-16 03:53:10 +08:00
Debug ( 1 , ( " %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 ) ) ;
2003-03-26 20:03:37 +08:00
}
return ( true ) ;
}
int Zone : : Load ( Monitor * monitor , Zone * * & zones )
{
2003-07-04 04:39:47 +08:00
static char sql [ BUFSIZ ] ;
2004-04-20 00:02:17 +08:00
snprintf ( sql , sizeof ( sql ) , " select Id,Name,Type+0,Units,LoX,LoY,HiX,HiY,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 ( ) ) ;
2003-03-26 20:03:37 +08:00
if ( mysql_query ( & dbconn , sql ) )
{
Error ( ( " Can't run query: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
MYSQL_RES * result = mysql_store_result ( & dbconn ) ;
if ( ! result )
{
Error ( ( " Can't use query result: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
int n_zones = mysql_num_rows ( result ) ;
2004-03-17 18:28:07 +08:00
Debug ( 1 , ( " Got %d zones for monitor %s " , n_zones , monitor - > Name ( ) ) ) ;
2003-03-26 20:03:37 +08:00
delete [ ] zones ;
zones = new Zone * [ n_zones ] ;
for ( int i = 0 ; MYSQL_ROW dbrow = mysql_fetch_row ( result ) ; i + + )
{
2004-01-27 20:27:22 +08:00
int col = 0 ;
int Id = atoi ( dbrow [ col + + ] ) ;
const char * Name = dbrow [ col + + ] ;
int Type = atoi ( dbrow [ col + + ] ) ;
const char * Units = dbrow [ col + + ] ;
int LoX = atoi ( dbrow [ col + + ] ) ;
int LoY = atoi ( dbrow [ col + + ] ) ;
int HiX = atoi ( dbrow [ col + + ] ) ;
int HiY = atoi ( dbrow [ col + + ] ) ;
int AlarmRGB = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
2004-02-16 04:02:41 +08:00
int CheckMethod = atoi ( dbrow [ col + + ] ) ;
2004-01-27 20:27:22 +08:00
int MinPixelThreshold = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int MaxPixelThreshold = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int MinAlarmPixels = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int MaxAlarmPixels = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int FilterX = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int FilterY = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int MinFilterPixels = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int MaxFilterPixels = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
int MinBlobPixels = dbrow [ col ] ? atoi ( dbrow [ col ] ) : 0 ; col + + ;
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 + + ;
2003-03-26 20:03:37 +08:00
if ( ! strcmp ( Units , " Percent " ) )
{
2003-05-02 23:03:16 +08:00
LoX = ( LoX * ( monitor - > Width ( ) - 1 ) ) / 100 ;
LoY = ( LoY * ( monitor - > Height ( ) - 1 ) ) / 100 ;
HiX = ( HiX * ( monitor - > Width ( ) - 1 ) ) / 100 ;
HiY = ( HiY * ( monitor - > Height ( ) - 1 ) ) / 100 ;
2004-03-04 21:16:18 +08:00
Box box ( LoX , LoY , HiX , HiY ) ;
MinAlarmPixels = ( MinAlarmPixels * box . Width ( ) * box . Height ( ) ) / 100 ;
MaxAlarmPixels = ( MaxAlarmPixels * box . Width ( ) * box . Height ( ) ) / 100 ;
MinFilterPixels = ( MinFilterPixels * box . Width ( ) * box . Height ( ) ) / 100 ;
MaxFilterPixels = ( MaxFilterPixels * box . Width ( ) * box . Height ( ) ) / 100 ;
MinBlobPixels = ( MinBlobPixels * box . Width ( ) * box . Height ( ) ) / 100 ;
MaxBlobPixels = ( MaxBlobPixels * box . Width ( ) * box . Height ( ) ) / 100 ;
2003-03-26 20:03:37 +08:00
}
if ( atoi ( dbrow [ 2 ] ) = = Zone : : INACTIVE )
{
zones [ i ] = new Zone ( monitor , Id , Name , Box ( LoX , LoY , HiX , HiY ) ) ;
}
else
{
2004-02-16 04:02:41 +08:00
zones [ i ] = new Zone ( monitor , Id , Name , ( Zone : : ZoneType ) Type , Box ( LoX , LoY , HiX , HiY ) , AlarmRGB , ( Zone : : CheckMethod ) CheckMethod , MinPixelThreshold , MaxPixelThreshold , MinAlarmPixels , MaxAlarmPixels , Coord ( FilterX , FilterY ) , MinFilterPixels , MaxFilterPixels , MinBlobPixels , MaxBlobPixels , MinBlobs , MaxBlobs ) ;
2003-03-26 20:03:37 +08:00
}
}
if ( mysql_errno ( & dbconn ) )
{
Error ( ( " Can't fetch row: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
// Yadda yadda
mysql_free_result ( result ) ;
return ( n_zones ) ;
}
2004-01-15 05:26:47 +08:00
bool Zone : : DumpSettings ( char * output , bool /*verbose*/ )
2003-03-26 20:03:37 +08:00
{
output [ 0 ] = 0 ;
sprintf ( output + strlen ( output ) , " Id : %d \n " , id ) ;
sprintf ( output + strlen ( output ) , " Label : %s \n " , label ) ;
sprintf ( output + strlen ( output ) , " Type: %d - %s \n " , type ,
type = = ACTIVE ? " Active " : (
type = = INCLUSIVE ? " Inclusive " : (
type = = EXCLUSIVE ? " Exclusive " : (
2003-04-15 19:54:08 +08:00
type = = PRECLUSIVE ? " Preclusive " : (
type = = INACTIVE ? " Inactive " : " Unknown "
2003-04-13 20:20:00 +08:00
) ) ) ) ) ;
2003-03-26 20:03:37 +08:00
sprintf ( output + strlen ( output ) , " Limits : %d,%d - %d,%d \n " , limits . LoX ( ) , limits . LoY ( ) , limits . HiX ( ) , limits . HiY ( ) ) ;
sprintf ( output + strlen ( output ) , " Alarm RGB : %06x \n " , alarm_rgb ) ;
2004-02-16 04:02:41 +08:00
sprintf ( output + strlen ( output ) , " Check Method: %d - %s \n " , check_method ,
check_method = = ALARMED_PIXELS ? " Alarmed Pixels " : (
check_method = = FILTERED_PIXELS ? " FilteredPixels " : (
check_method = = BLOBS ? " Blobs " : " Unknown "
) ) ) ;
2004-01-27 20:27:22 +08:00
sprintf ( output + strlen ( output ) , " Min Pixel Threshold : %d \n " , min_pixel_threshold ) ;
sprintf ( output + strlen ( output ) , " Max Pixel Threshold : %d \n " , max_pixel_threshold ) ;
2003-03-26 20:03:37 +08:00
sprintf ( output + strlen ( output ) , " Min Alarm Pixels : %d \n " , min_alarm_pixels ) ;
sprintf ( output + strlen ( output ) , " Max Alarm Pixels : %d \n " , max_alarm_pixels ) ;
sprintf ( output + strlen ( output ) , " Filter Box : %d,%d \n " , filter_box . X ( ) , filter_box . Y ( ) ) ;
sprintf ( output + strlen ( output ) , " Min Filter Pixels : %d \n " , min_filter_pixels ) ;
sprintf ( output + strlen ( output ) , " Max Filter Pixels : %d \n " , max_filter_pixels ) ;
sprintf ( output + strlen ( output ) , " Min Blob Pixels : %d \n " , min_blob_pixels ) ;
sprintf ( output + strlen ( output ) , " Max Blob Pixels : %d \n " , max_blob_pixels ) ;
sprintf ( output + strlen ( output ) , " Min Blobs : %d \n " , min_blobs ) ;
sprintf ( output + strlen ( output ) , " Max Blobs : %d \n " , max_blobs ) ;
return ( true ) ;
}