diff --git a/src/alg.cpp b/src/alg.cpp index e10afb95..e39d8c7c 100644 --- a/src/alg.cpp +++ b/src/alg.cpp @@ -38,158 +38,8 @@ typedef struct { short y, xl, xr, dy; } Segment; -void alg_locate_center_size(struct ctx_images *imgs, int width, int height, struct ctx_coord *cent) -{ - unsigned char *out = imgs->image_motion.image_norm; - int *labels = imgs->labels; - int x, y, centc = 0, xdist = 0, ydist = 0; - cent->x = 0; - cent->y = 0; - cent->maxx = 0; - cent->maxy = 0; - cent->minx = width; - cent->miny = height; - - /* If Labeling enabled - locate center of largest labelgroup. */ - if (imgs->labelsize_max) { - /* Locate largest labelgroup */ - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - if (*(labels++) & 32768) { - cent->x += x; - cent->y += y; - centc++; - } - } - } - - } else { - /* Locate movement */ - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - if (*(out++)) { - cent->x += x; - cent->y += y; - centc++; - } - } - } - - } - - if (centc) { - cent->x = cent->x / centc; - cent->y = cent->y / centc; - } - - /* Now we find the size of the Motion. */ - - /* First reset pointers back to initial value. */ - centc = 0; - labels = imgs->labels; - out = imgs->image_motion.image_norm; - - /* If Labeling then we find the area around largest labelgroup instead. */ - if (imgs->labelsize_max) { - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - if (*(labels++) & 32768) { - if (x > cent->x) { - xdist += x - cent->x; - } else if (x < cent->x) { - xdist += cent->x - x; - } - - if (y > cent->y) { - ydist += y - cent->y; - } else if (y < cent->y) { - ydist += cent->y - y; - } - - centc++; - } - } - } - - } else { - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - if (*(out++)) { - if (x > cent->x) { - xdist += x - cent->x; - } else if (x < cent->x) { - xdist += cent->x - x; - } - - if (y > cent->y) { - ydist += y - cent->y; - } else if (y < cent->y) { - ydist += cent->y - y; - } - - centc++; - } - } - } - - } - - if (centc) { - cent->minx = cent->x - xdist / centc * 2; - cent->maxx = cent->x + xdist / centc * 2; - /* - * Make the box a little bigger in y direction to make sure the - * heads fit in so we multiply by 3 instead of 2 which seems to - * to work well in practical. - */ - cent->miny = cent->y - ydist / centc * 3; - cent->maxy = cent->y + ydist / centc * 2; - } - - if (cent->maxx > width - 1) { - cent->maxx = width - 1; - } else if (cent->maxx < 0) { - cent->maxx = 0; - } - - if (cent->maxy > height - 1) { - cent->maxy = height - 1; - } else if (cent->maxy < 0) { - cent->maxy = 0; - } - - if (cent->minx > width - 1) { - cent->minx = width - 1; - } else if (cent->minx < 0) { - cent->minx = 0; - } - - if (cent->miny > height - 1) { - cent->miny = height - 1; - } else if (cent->miny < 0) { - cent->miny = 0; - } - - /* Align for better locate box handling */ - cent->minx += cent->minx % 2; - cent->miny += cent->miny % 2; - cent->maxx -= cent->maxx % 2; - cent->maxy -= cent->maxy % 2; - - cent->width = cent->maxx - cent->minx; - cent->height = cent->maxy - cent->miny; - - /* - * We want to center Y coordinate to be the center of the action. - * The head of a person is important so we correct the cent.y coordinate - * to match the correction to include a persons head that we just did above. - */ - cent->y = (cent->miny + cent->maxy) / 2; - -} - -void alg_noise_tune(struct ctx_cam *cam, unsigned char *new_var) +void alg_noise_tune(ctx_cam *cam) { struct ctx_images *imgs = &cam->imgs; int i; @@ -197,11 +47,13 @@ void alg_noise_tune(struct ctx_cam *cam, unsigned char *new_var) int diff, sum = 0, count = 0; unsigned char *mask = imgs->mask; unsigned char *smartmask = imgs->smartmask_final; + unsigned char *new_img = cam->imgs.image_vprvcy; + i = imgs->motionsize; for (; i > 0; i--) { - diff = ABS(*ref - *new_var); + diff = ABS(*ref - *new_img); if (mask) { diff = ((diff * *mask++) / 255); @@ -213,7 +65,7 @@ void alg_noise_tune(struct ctx_cam *cam, unsigned char *new_var) } ref++; - new_var++; + new_img++; smartmask++; } @@ -226,15 +78,19 @@ void alg_noise_tune(struct ctx_cam *cam, unsigned char *new_var) cam->noise = 4 + (cam->noise + sum) / 2; } -void alg_threshold_tune(struct ctx_cam *cam, int diffs, int motion) +void alg_threshold_tune(ctx_cam *cam) { - int i; - int sum = 0, top = diffs; + int i, top; + int sum = 0; + int diffs = cam->current_image->diffs; + int motion = cam->detecting_motion; if (!diffs) { return; } + top = diffs; + if (motion) { diffs = cam->threshold / 4; } @@ -341,7 +197,7 @@ static int alg_iflood(int x, int y, int width, int height, return count; } -static int alg_labeling(struct ctx_cam *cam) +static int alg_labeling(ctx_cam *cam) { struct ctx_images *imgs = &cam->imgs; unsigned char *out = imgs->image_motion.image_norm; @@ -646,7 +502,7 @@ static int alg_erode5(unsigned char *img, int width, int height, void *buffer, u return sum; } -void alg_despeckle(struct ctx_cam *cam) +static void alg_despeckle(ctx_cam *cam) { int diffs, width, height, done, i, len; unsigned char *out, *common_buffer; @@ -716,7 +572,7 @@ void alg_despeckle(struct ctx_cam *cam) return; } -void alg_tune_smartmask(struct ctx_cam *cam) +void alg_tune_smartmask(ctx_cam *cam) { int i, diff; int motionsize = cam->imgs.motionsize; @@ -765,92 +621,119 @@ void alg_tune_smartmask(struct ctx_cam *cam) /* Increment for *smartmask_buffer in alg_diff_standard. */ #define SMARTMASK_SENSITIVITY_INCR 5 -static int alg_diff_nomask(struct ctx_cam *cam, unsigned char *new_var) +static void alg_diff_nomask(ctx_cam *cam) { unsigned char *ref = cam->imgs.ref; unsigned char *out = cam->imgs.image_motion.image_norm; + unsigned char *new_img = cam->imgs.image_vprvcy; int i, curdiff; int imgsz = cam->imgs.motionsize; - int diffs = 0; + int diffs = 0, diffs_net = 0; int noise = cam->noise; + int lrgchg = cam->conf->threshold_ratio_change; memset(out + imgsz, 128, (imgsz / 2)); memset(out, 0, imgsz); for (i = 0; i < imgsz; i++) { - curdiff = abs(*ref - *new_var); - if (curdiff > noise) { - *out = *new_var; - diffs++; - } - out++; - ref++; - new_var++; - } - - struct timespec ts2; - - clock_gettime(CLOCK_REALTIME, &ts2); - - return diffs; -} - -static int alg_diff_mask(struct ctx_cam *cam, unsigned char *new_img) -{ - unsigned char *ref = cam->imgs.ref; - unsigned char *out = cam->imgs.image_motion.image_norm; - unsigned char *mask = cam->imgs.mask; - - int i, curdiff; - int imgsz = cam->imgs.motionsize; - int diffs = 0; - int noise = cam->noise; - - memset(out + imgsz, 128, (imgsz / 2)); - memset(out, 0, imgsz); - - for (i = 0; i < imgsz; i++) { - curdiff = abs(*ref - *new_img); - if (mask) { - curdiff = ((curdiff * *mask) / 255); - mask++; - } - - if (curdiff > noise) { + curdiff = (*ref - *new_img); + if (abs(curdiff) > noise) { *out = *new_img; diffs++; + if (curdiff > lrgchg) { + diffs_net++; + } else if (curdiff < -lrgchg) { + diffs_net--; + } } out++; ref++; new_img++; } + cam->current_image->diffs_raw = diffs; + cam->current_image->diffs = diffs; + + if (diffs > 0 ) { + cam->current_image->diffs_ratio = (abs(diffs_net) * 100) / diffs; + } else { + cam->current_image->diffs_ratio = 100; + } - return diffs; } -static int alg_diff_smart(struct ctx_cam *cam, unsigned char *new_img) +static void alg_diff_mask(ctx_cam *cam) +{ + unsigned char *ref = cam->imgs.ref; + unsigned char *out = cam->imgs.image_motion.image_norm; + unsigned char *mask = cam->imgs.mask; + unsigned char *new_img = cam->imgs.image_vprvcy; + + int i, curdiff; + int imgsz = cam->imgs.motionsize; + int diffs = 0, diffs_net = 0; + int noise = cam->noise; + int lrgchg = cam->conf->threshold_ratio_change; + + memset(out + imgsz, 128, (imgsz / 2)); + memset(out, 0, imgsz); + + for (i = 0; i < imgsz; i++) { + curdiff = (*ref - *new_img); + if (mask) { + curdiff = ((curdiff * *mask) / 255); + } + + if (abs(curdiff) > noise) { + *out = *new_img; + diffs++; + if (curdiff > lrgchg) { + diffs_net++; + } else if (curdiff < -lrgchg) { + diffs_net--; + } + } + + out++; + ref++; + new_img++; + mask++; + } + cam->current_image->diffs_raw = diffs; + cam->current_image->diffs = diffs; + + if (diffs > 0 ) { + cam->current_image->diffs_ratio = (abs(diffs_net) * 100) / diffs; + } else { + cam->current_image->diffs_ratio = 100; + } + +} + +static void alg_diff_smart(ctx_cam *cam) { unsigned char *ref = cam->imgs.ref; unsigned char *out = cam->imgs.image_motion.image_norm; unsigned char *smartmask_final = cam->imgs.smartmask_final; + unsigned char *new_img = cam->imgs.image_vprvcy; int i, curdiff; int imgsz = cam->imgs.motionsize; - int diffs = 0; + int diffs = 0, diffs_net = 0; int noise = cam->noise; int smartmask_speed = cam->smartmask_speed; int *smartmask_buffer = cam->imgs.smartmask_buffer; + int lrgchg = cam->conf->threshold_ratio_change; imgsz = cam->imgs.motionsize; memset(out + imgsz, 128, (imgsz / 2)); memset(out, 0, imgsz); for (i = 0; i < imgsz; i++) { - curdiff = abs(*ref - *new_img); + curdiff = (*ref - *new_img); if (smartmask_speed) { - if (curdiff > noise) { + if (abs(curdiff) > noise) { if (cam->event_nr != cam->prev_event) { (*smartmask_buffer) += SMARTMASK_SENSITIVITY_INCR; } @@ -862,46 +745,57 @@ static int alg_diff_smart(struct ctx_cam *cam, unsigned char *new_img) smartmask_buffer++; } /* Pixel still in motion after all the masks? */ - if (curdiff > noise) { + if (abs(curdiff) > noise) { *out = *new_img; diffs++; + if (curdiff > lrgchg) { + diffs_net++; + } else if (curdiff < -lrgchg) { + diffs_net--; + } } - out++; ref++; new_img++; } + cam->current_image->diffs_raw = diffs; + cam->current_image->diffs = diffs; - return diffs; + if (diffs > 0 ) { + cam->current_image->diffs_ratio = (abs(diffs_net) * 100) / diffs; + } else { + cam->current_image->diffs_ratio = 100; + } } -static int alg_diff_masksmart(struct ctx_cam *cam, unsigned char *new_img) +static void alg_diff_masksmart(ctx_cam *cam) { unsigned char *ref = cam->imgs.ref; unsigned char *out = cam->imgs.image_motion.image_norm; unsigned char *mask = cam->imgs.mask; unsigned char *smartmask_final = cam->imgs.smartmask_final; + unsigned char *new_img = cam->imgs.image_vprvcy; int i, curdiff; int imgsz = cam->imgs.motionsize; - int diffs = 0; + int diffs = 0, diffs_net = 0; int noise = cam->noise; int smartmask_speed = cam->smartmask_speed; int *smartmask_buffer = cam->imgs.smartmask_buffer; + int lrgchg = cam->conf->threshold_ratio_change; imgsz= cam->imgs.motionsize; memset(out + imgsz, 128, (imgsz / 2)); memset(out, 0, imgsz); for (i = 0; i < imgsz; i++) { - curdiff = abs(*ref - *new_img); + curdiff = (*ref - *new_img); if (mask) { curdiff = ((curdiff * *mask) / 255); - mask++; } if (smartmask_speed) { - if (curdiff > noise) { + if (abs(curdiff) > noise) { if (cam->event_nr != cam->prev_event) { (*smartmask_buffer) += SMARTMASK_SENSITIVITY_INCR; } @@ -912,30 +806,44 @@ static int alg_diff_masksmart(struct ctx_cam *cam, unsigned char *new_img) smartmask_final++; smartmask_buffer++; } + /* Pixel still in motion after all the masks? */ - if (curdiff > noise) { + if (abs(curdiff) > noise) { *out = *new_img; diffs++; + if (curdiff > lrgchg) { + diffs_net++; + } else if (curdiff < -lrgchg) { + diffs_net--; + } } out++; ref++; new_img++; + mask++; + } + + cam->current_image->diffs_raw = diffs; + cam->current_image->diffs = diffs; + + if (diffs > 0 ) { + cam->current_image->diffs_ratio = (abs(diffs_net) * 100) / diffs; + } else { + cam->current_image->diffs_ratio = 100; } - return diffs; } - -static char alg_diff_fast(struct ctx_cam *cam, int max_n_changes, unsigned char *new_var) +static bool alg_diff_fast(ctx_cam *cam) { struct ctx_images *imgs = &cam->imgs; - int i; - int diffs = 0; + int i, curdiff, diffs = 0; int step = cam->imgs.motionsize / 10000; int noise = cam->noise; + int max_n_changes = cam->conf->threshold / 2; unsigned char *ref = imgs->ref; - int curdiff; + unsigned char *new_img = cam->imgs.image_vprvcy; if (!step % 2) { step++; @@ -946,61 +854,40 @@ static char alg_diff_fast(struct ctx_cam *cam, int max_n_changes, unsigned char i = imgs->motionsize; for (; i > 0; i -= step) { - curdiff = abs(*ref - *new_var); /* Using a temp variable is 12% faster. */ + curdiff = abs(*ref - *new_img); /* Using a temp variable is 12% faster. */ if (curdiff > noise) { diffs++; if (diffs > max_n_changes) { - - //MOTION_LOG(ERR, TYPE_ALL, NO_ERRNO - //,"Lots of fast diffs %d detected.", diffs); - - return 1; + return true; } } ref += step; - new_var += step; + new_img += step; } - //MOTION_LOG(ERR, TYPE_ALL, NO_ERRNO - // ,"Fast Diffs %d detected.", diffs); - - return 0; + return false; } -static void alg_diff_standard(struct ctx_cam *cam) +static void alg_diff_standard(ctx_cam *cam) { if (cam->smartmask_speed == 0) { if (cam->imgs.mask == NULL) { - cam->current_image->diffs = alg_diff_nomask(cam, cam->imgs.image_vprvcy); + alg_diff_nomask(cam); } else { - cam->current_image->diffs = alg_diff_mask(cam, cam->imgs.image_vprvcy); + alg_diff_mask(cam); } } else { if (cam->imgs.mask == NULL) { - cam->current_image->diffs = alg_diff_smart(cam, cam->imgs.image_vprvcy); + alg_diff_smart(cam); } else { - cam->current_image->diffs = alg_diff_masksmart(cam, cam->imgs.image_vprvcy); + alg_diff_masksmart(cam); } } } -void alg_diff(struct ctx_cam *cam) -{ - - if (cam->detecting_motion || cam->motapp->setup_mode) { - alg_diff_standard(cam); - } else { - if (alg_diff_fast(cam, cam->conf->threshold / 2, cam->imgs.image_vprvcy)) { - alg_diff_standard(cam); - } else { - cam->current_image->diffs = 0; - } - } -} - -void alg_lightswitch(struct ctx_cam *cam) +static void alg_lightswitch(ctx_cam *cam) { if (cam->conf->lightswitch_percent >= 1 && !cam->lost_connection) { @@ -1028,7 +915,7 @@ void alg_lightswitch(struct ctx_cam *cam) * action - UPDATE_REF_FRAME or RESET_REF_FRAME * */ -void alg_update_reference_frame(struct ctx_cam *cam, int action) +void alg_update_reference_frame(ctx_cam *cam, int action) { int accept_timer = cam->lastrate * cam->conf->static_object_time; int i, threshold_ref; @@ -1091,7 +978,7 @@ void alg_new_update_frame(ctx_cam *cam) } /*Calculate the center location of changes*/ -static void alg_new_location_center(ctx_cam *cam) +static void alg_location_center(ctx_cam *cam) { int width = cam->imgs.width; int height = cam->imgs.height; @@ -1134,7 +1021,7 @@ static void alg_new_location_center(ctx_cam *cam) } /*Calculate distribution and variances of changes*/ -static void alg_new_location_dist(ctx_cam *cam) +static void alg_location_dist(ctx_cam *cam) { ctx_images *imgs = &cam->imgs; int width = cam->imgs.width; @@ -1162,7 +1049,6 @@ static void alg_new_location_dist(ctx_cam *cam) if (*(out++)) { variance_x += ((x - cent->x) * (x - cent->x)); variance_y += ((y - cent->y) * (y - cent->y)); - /* ToDo: We should store this number for the variance calc...*/ distance_mean += sqrt( ((x - cent->x) * (x - cent->x)) + ((y - cent->y) * (y - cent->y))); @@ -1218,7 +1104,7 @@ static void alg_new_location_dist(ctx_cam *cam) } /* Ensure min/max are within limits*/ -static void alg_new_location_minmax(ctx_cam *cam) +static void alg_location_minmax(ctx_cam *cam) { int width = cam->imgs.width; @@ -1261,24 +1147,20 @@ static void alg_new_location_minmax(ctx_cam *cam) } /* Determine the location and standard deviations of changes*/ -static void alg_new_location(ctx_cam *cam) +void alg_location(ctx_cam *cam) { - alg_new_location_center(cam); + alg_location_center(cam); - alg_new_location_dist(cam); + alg_location_dist(cam); - alg_new_location_minmax(cam); + alg_location_minmax(cam); } /* Apply user or default thresholds on standard deviations*/ -static void alg_new_stddev(ctx_cam *cam) +void alg_stddev(ctx_cam *cam) { - long chk_stddev; - - return; - MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO, "dev_x %d dev_y %d dev_xy %d, diff %d ratio %d" , cam->current_image->location.stddev_x , cam->current_image->location.stddev_y @@ -1304,101 +1186,29 @@ static void alg_new_stddev(ctx_cam *cam) } } - if (cam->current_image->diffs_ratio < cam->conf->threshold_ratio) { - cam->current_image->diffs = 0; - } - - /* Default standard deviation testing. The 8 is just a developer choice of - * that would say if the deviation is within 1/8th of the screen count it - */ - if ((cam->conf->threshold_sdevxy == 0) && - (cam->conf->threshold_sdevx == 0) && - (cam->conf->threshold_sdevy == 0)) { - - chk_stddev = (long)((cam->imgs.width / 8) - cam->current_image->location.stddev_x); - if (chk_stddev < 0) { - cam->current_image->diffs = 0; - return; - } - - chk_stddev = (long)((cam->imgs.height / 8) - cam->current_image->location.stddev_y); - if (chk_stddev < 0) { - cam->current_image->diffs = 0; - return; - } - - chk_stddev = (long)((sqrt(cam->imgs.height * cam->imgs.width) / 8) - - cam->current_image->location.stddev_xy); - if (chk_stddev < 0) { - cam->current_image->diffs = 0; - return; - } - } - return; } -/* Determine base differences */ -static void alg_new_diff_base(ctx_cam *cam) +void alg_diff(ctx_cam *cam) { - ctx_images *imgs = &cam->imgs; - int indx = 0; - int indx_en = imgs->motionsize; - long diffs = 0; - long diffs_net = 0; - int noise = cam->noise; - unsigned char *ref = imgs->ref; - unsigned char *out = imgs->image_motion.image_norm; - unsigned char *mask = imgs->mask; - unsigned char *new_var = cam->imgs.image_vprvcy; - unsigned char curdiff; - - memset(out + indx_en, 128, indx_en / 2); /* Motion pictures are now b/w i.o. green */ - memset(out, 0, indx_en); - - for (indx = 0; indx < indx_en; indx++) { - curdiff = (int)(abs(*ref - *new_var)); - if (mask) { - curdiff = ((int)(curdiff * *mask++) / 255); - } - if (curdiff > noise) { - *out = *new_var; - diffs++; - if ((int)(*ref - *new_var) > 0) { - diffs_net++; - } else { - diffs_net--; - } - } - out++; - ref++; - new_var++; - } - cam->current_image->diffs_raw = diffs; - cam->current_image->diffs = diffs; - - diffs_net = abs(diffs_net); - if (diffs_net > 0 ) { - cam->current_image->diffs_ratio = (diffs *10) / diffs_net; + if (cam->detecting_motion || cam->motapp->setup_mode) { + alg_diff_standard(cam); } else { - cam->current_image->diffs_ratio = 0; + if (alg_diff_fast(cam)) { + alg_diff_standard(cam); + } else { + cam->current_image->diffs = 0; + cam->current_image->diffs_raw = 0; + cam->current_image->diffs_ratio = 100; + } } - return; -} - -void alg_new_diff(ctx_cam *cam) -{ - - alg_new_diff_base(cam); + alg_lightswitch(cam); alg_despeckle(cam); - alg_new_location(cam); - - alg_new_stddev(cam); - return; + } diff --git a/src/alg.hpp b/src/alg.hpp index 50c8458b..d4683eea 100644 --- a/src/alg.hpp +++ b/src/alg.hpp @@ -20,18 +20,12 @@ #ifndef _INCLUDE_ALG_HPP_ #define _INCLUDE_ALG_HPP_ - struct ctx_coord; - - void alg_locate_center_size(struct ctx_images *imgs, int width, int height, struct ctx_coord *cent); - void alg_diff(struct ctx_cam *cam); - void alg_lightswitch(struct ctx_cam *cam); - void alg_noise_tune(struct ctx_cam *cam, unsigned char *new_var); - void alg_threshold_tune(struct ctx_cam *cam, int diffs, int motion); - void alg_despeckle(struct ctx_cam *cam); - void alg_tune_smartmask(struct ctx_cam *cam); - void alg_update_reference_frame(struct ctx_cam *cam, int action); - void alg_new_update_frame(ctx_cam *cam); - void alg_new_diff(ctx_cam *cam); - + void alg_diff(ctx_cam *cam); + void alg_noise_tune(ctx_cam *cam); + void alg_threshold_tune(ctx_cam *cam); + void alg_tune_smartmask(ctx_cam *cam); + void alg_update_reference_frame(ctx_cam *cam, int action); + void alg_stddev(ctx_cam *cam); + void alg_location(ctx_cam *cam); #endif /* _INCLUDE_ALG_HPP_ */ diff --git a/src/conf.cpp b/src/conf.cpp index 5ce947a7..739be51d 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -81,13 +81,13 @@ struct ctx_parm config_parms[] = { {"text_event", PARM_TYP_STRING, PARM_CAT_04, WEBUI_LEVEL_LIMITED }, {"emulate_motion", PARM_TYP_BOOL, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, - {"primary_method", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"threshold", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"threshold_maximum", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"threshold_sdevx", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"threshold_sdevy", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"threshold_sdevxy", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"threshold_ratio", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, + {"threshold_ratio_change", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"threshold_tune", PARM_TYP_BOOL, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"secondary_interval", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, {"secondary_method", PARM_TYP_INT, PARM_CAT_05, WEBUI_LEVEL_LIMITED }, @@ -1074,25 +1074,6 @@ static void conf_edit_emulate_motion(struct ctx_cam *cam, std::string &parm, enu MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","emulate_motion",_("emulate_motion")); } -static void conf_edit_primary_method(struct ctx_cam *cam, std::string &parm, enum PARM_ACT pact) -{ - int parm_in; - if (pact == PARM_ACT_DFLT) { - cam->conf->primary_method = 0; - } else if (pact == PARM_ACT_SET) { - parm_in = atoi(parm.c_str()); - if ((parm_in < 0) || (parm_in > 2)) { - MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid primary method %d"),parm_in); - } else { - cam->conf->primary_method = parm_in; - } - } else if (pact == PARM_ACT_GET) { - parm = std::to_string(cam->conf->primary_method); - } - return; - MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","primary_method",_("primary_method")); -} - static void conf_edit_threshold(struct ctx_cam *cam, std::string &parm, enum PARM_ACT pact) { int parm_in; @@ -1192,10 +1173,10 @@ static void conf_edit_threshold_ratio(struct ctx_cam *cam, std::string &parm, en { int parm_in; if (pact == PARM_ACT_DFLT) { - cam->conf->threshold_ratio = 999999; /* Arbitrary large value */ + cam->conf->threshold_ratio = 0; } else if (pact == PARM_ACT_SET) { parm_in = atoi(parm.c_str()); - if ((parm_in < 0) ) { + if ((parm_in < 0) || (parm_in > 100) ) { MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid threshold_ratio %d"),parm_in); } else { cam->conf->threshold_ratio = parm_in; @@ -1207,6 +1188,25 @@ static void conf_edit_threshold_ratio(struct ctx_cam *cam, std::string &parm, en MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","threshold_ratio",_("threshold_ratio")); } +static void conf_edit_threshold_ratio_change(struct ctx_cam *cam, std::string &parm, enum PARM_ACT pact) +{ + int parm_in; + if (pact == PARM_ACT_DFLT) { + cam->conf->threshold_ratio_change = 64; + } else if (pact == PARM_ACT_SET) { + parm_in = atoi(parm.c_str()); + if ((parm_in < 0) || (parm_in > 255) ) { + MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid threshold_ratio_change %d"),parm_in); + } else { + cam->conf->threshold_ratio_change = parm_in; + } + } else if (pact == PARM_ACT_GET) { + parm = std::to_string(cam->conf->threshold_ratio_change); + } + return; + MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","threshold_ratio_change",_("threshold_ratio_change")); +} + static void conf_edit_threshold_tune(struct ctx_cam *cam, std::string &parm, enum PARM_ACT pact) { if (pact == PARM_ACT_DFLT) { @@ -2830,13 +2830,13 @@ static void conf_edit_cat05(struct ctx_cam *cam, std::string parm_nm , std::string &parm_val, enum PARM_ACT pact) { if (parm_nm == "emulate_motion") { conf_edit_emulate_motion(cam, parm_val, pact); - } else if (parm_nm == "primary_method") { conf_edit_primary_method(cam, parm_val, pact); } else if (parm_nm == "threshold") { conf_edit_threshold(cam, parm_val, pact); } else if (parm_nm == "threshold_maximum") { conf_edit_threshold_maximum(cam, parm_val, pact); } else if (parm_nm == "threshold_sdevx") { conf_edit_threshold_sdevx(cam, parm_val, pact); } else if (parm_nm == "threshold_sdevy") { conf_edit_threshold_sdevy(cam, parm_val, pact); } else if (parm_nm == "threshold_sdevxy") { conf_edit_threshold_sdevxy(cam, parm_val, pact); } else if (parm_nm == "threshold_ratio") { conf_edit_threshold_ratio(cam, parm_val, pact); + } else if (parm_nm == "threshold_ratio_change") { conf_edit_threshold_ratio_change(cam, parm_val, pact); } else if (parm_nm == "threshold_tune") { conf_edit_threshold_tune(cam, parm_val, pact); } else if (parm_nm == "secondary_interval") { conf_edit_secondary_interval(cam, parm_val, pact); } else if (parm_nm == "secondary_method") { conf_edit_secondary_method(cam, parm_val, pact); diff --git a/src/conf.hpp b/src/conf.hpp index 5b693c3a..660d99bb 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -64,13 +64,13 @@ /* Motion detection configuration parameters */ bool emulate_motion; - int primary_method; int threshold; int threshold_maximum; int threshold_sdevx; int threshold_sdevy; int threshold_sdevxy; int threshold_ratio; + int threshold_ratio_change; bool threshold_tune; int secondary_interval; int secondary_method; diff --git a/src/motion_loop.cpp b/src/motion_loop.cpp index 4e88529b..66847e66 100644 --- a/src/motion_loop.cpp +++ b/src/motion_loop.cpp @@ -660,12 +660,7 @@ static void mlp_init_ref(struct ctx_cam *cam) memcpy(cam->imgs.image_vprvcy, cam->current_image->image_norm, cam->imgs.size_norm); - if (cam->conf->primary_method == 0) { - alg_update_reference_frame(cam, RESET_REF_FRAME); - } else if (cam->conf->primary_method == 1) { - //alg_new_update_frame(cam); - alg_update_reference_frame(cam, RESET_REF_FRAME); - } + alg_update_reference_frame(cam, RESET_REF_FRAME); } @@ -1121,16 +1116,11 @@ static void mlp_detection(struct ctx_cam *cam) } if ( !cam->pause ) { - if (cam->conf->primary_method == 0) { - alg_diff(cam); - alg_lightswitch(cam); - alg_despeckle(cam); - alg_tune_smartmask(cam); - } else if (cam->conf->primary_method == 1) { - alg_new_diff(cam); - } + alg_diff(cam); } else { cam->current_image->diffs = 0; + cam->current_image->diffs_raw = 0; + cam->current_image->diffs_ratio = 100; } } @@ -1140,21 +1130,27 @@ static void mlp_tuning(struct ctx_cam *cam) if ((cam->conf->noise_tune && cam->shots == 0) && (!cam->detecting_motion && (cam->current_image->diffs <= cam->threshold))) { - alg_noise_tune(cam, cam->imgs.image_vprvcy); + alg_noise_tune(cam); } if (cam->conf->threshold_tune) { - alg_threshold_tune(cam, cam->current_image->diffs, cam->detecting_motion); + alg_threshold_tune(cam); } if ((cam->current_image->diffs > cam->threshold) && (cam->current_image->diffs < cam->threshold_maximum)) { - alg_locate_center_size(&cam->imgs - , cam->imgs.width - , cam->imgs.height - , &cam->current_image->location); + alg_location(cam); + alg_stddev(cam); + } + if (cam->current_image->diffs_ratio < cam->conf->threshold_ratio) { + cam->current_image->diffs = 0; + } + + alg_tune_smartmask(cam); + + alg_update_reference_frame(cam, UPDATE_REF_FRAME); cam->previous_diffs = cam->current_image->diffs; @@ -1203,31 +1199,16 @@ static void mlp_overlay(struct ctx_cam *cam) } if (cam->motapp->setup_mode || (cam->stream.motion.cnct_count > 0)) { - if (cam->conf->primary_method == 0) { - sprintf(tmp, "D:%5d L:%3d N:%3d", cam->current_image->diffs, - cam->current_image->total_labels, cam->noise); - draw_text(cam->imgs.image_motion.image_norm, cam->imgs.width, cam->imgs.height, - cam->imgs.width - 10, cam->imgs.height - (30 * cam->text_scale), - tmp, cam->text_scale); - sprintf(tmp, "THREAD %d SETUP", cam->threadnr); - draw_text(cam->imgs.image_motion.image_norm, cam->imgs.width, cam->imgs.height, - cam->imgs.width - 10, cam->imgs.height - (10 * cam->text_scale), - tmp, cam->text_scale); - } else { - sprintf(tmp, "D:%5d xy:%3d x:%3d y:%3d" - , cam->current_image->diffs - , cam->current_image->location.stddev_xy - , cam->current_image->location.stddev_x - , cam->current_image->location.stddev_y); - draw_text(cam->imgs.image_motion.image_norm, cam->imgs.width, cam->imgs.height, - cam->imgs.width - 10, cam->imgs.height - (30 * cam->text_scale), - tmp, cam->text_scale); - sprintf(tmp, "center %d x %d", cam->current_image->location.x , cam->current_image->location.y ); - draw_text(cam->imgs.image_motion.image_norm, cam->imgs.width, cam->imgs.height, - cam->imgs.width - 10, cam->imgs.height - (10 * cam->text_scale), - tmp, cam->text_scale); + sprintf(tmp, "D:%5d L:%3d N:%3d", cam->current_image->diffs, + cam->current_image->total_labels, cam->noise); + draw_text(cam->imgs.image_motion.image_norm, cam->imgs.width, cam->imgs.height, + cam->imgs.width - 10, cam->imgs.height - (30 * cam->text_scale), + tmp, cam->text_scale); + sprintf(tmp, "THREAD %d SETUP", cam->threadnr); + draw_text(cam->imgs.image_motion.image_norm, cam->imgs.width, cam->imgs.height, + cam->imgs.width - 10, cam->imgs.height - (10 * cam->text_scale), + tmp, cam->text_scale); - } } /* Add text in lower left corner of the pictures */