From 2827e508888411e7e469de80650ec9f485e033d0 Mon Sep 17 00:00:00 2001 From: MrDave Date: Sat, 19 Oct 2019 17:32:20 -0600 Subject: [PATCH] Add alternative primary detection method --- src/alg.cpp | 320 ++++++++++++++++++++++++++++++++++++++++---- src/alg.hpp | 4 + src/conf.cpp | 16 +++ src/conf.hpp | 4 + src/conf_edit.cpp | 72 ++++++++++ src/motion_loop.cpp | 114 +++++++++------- 6 files changed, 456 insertions(+), 74 deletions(-) diff --git a/src/alg.cpp b/src/alg.cpp index f8411d89..32a3b667 100644 --- a/src/alg.cpp +++ b/src/alg.cpp @@ -13,16 +13,24 @@ #define MAX2(x, y) ((x) > (y) ? (x) : (y)) #define MAX3(x, y, z) ((x) > (y) ? ((x) > (z) ? (x) : (z)) : ((y) > (z) ? (y) : (z))) +#define NORM 100 +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define DIFF(x, y) (ABS((x)-(y))) +#define NDIFF(x, y) (ABS(x) * NORM / (ABS(x) + 2 * DIFF(x, y))) +#define MAXS 10000 /* max depth of stack */ + +#define PUSH(Y, XL, XR, DY) /* push new segment on stack */ \ + if (sp= 0 && Y+(DY) < height) \ + {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;} + +#define POP(Y, XL, XR, DY) /* pop segment off stack */ \ + {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;} + +typedef struct { + short y, xl, xr, dy; +} Segment; + -/* -struct segment { - struct ctx_coord coord; - int width; - int height; - int open; - int count; -}; -*/ /** * alg_locate_center_size @@ -171,11 +179,6 @@ void alg_locate_center_size(struct ctx_images *imgs, int width, int height, stru } -#define NORM 100 -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#define DIFF(x, y) (ABS((x)-(y))) -#define NDIFF(x, y) (ABS(x) * NORM / (ABS(x) + 2 * DIFF(x, y))) - /** * alg_noise_tune * @@ -263,19 +266,6 @@ void alg_threshold_tune(struct ctx_cam *cam, int diffs, int motion) * Parent segment was on line y - dy. dy = 1 or -1 */ -#define MAXS 10000 /* max depth of stack */ - -#define PUSH(Y, XL, XR, DY) /* push new segment on stack */ \ - if (sp= 0 && Y+(DY) < height) \ - {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;} - -#define POP(Y, XL, XR, DY) /* pop segment off stack */ \ - {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;} - -typedef struct { - short y, xl, xr, dy; -} Segment; - /** * iflood * @@ -979,3 +969,279 @@ void alg_update_reference_frame(struct ctx_cam *cam, int action) memset(cam->imgs.ref_dyn, 0, cam->imgs.motionsize * sizeof(*cam->imgs.ref_dyn)); } } + +/*Copy in new reference frame*/ +void alg_new_update_frame(ctx_cam *cam) { + + /* There used to be a lot more to this function before.....*/ + memcpy(cam->imgs.ref, cam->imgs.image_vprvcy, cam->imgs.size_norm); + +} + +/*Calculate the center location of changes*/ +static void alg_new_location_center(ctx_cam *cam) { + int width = cam->imgs.width; + int height = cam->imgs.height; + ctx_coord *cent = &cam->current_image->location; + unsigned char *out = cam->imgs.image_motion.image_norm; + int x, y, centc=0; + + cent->x = 0; + cent->y = 0; + + 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; + } + + /* This allows for the redcross and boxes to be drawn*/ + if (cent->x < 10) cent->x = 15; + if (cent->y < 10) cent->y = 15; + if ((cent->x + 10) > width) cent->x = width - 15; + if ((cent->y + 10) > height) cent->y = height - 15; + +} + +/*Calculate distribution and variances of changes*/ +static void alg_new_location_dist(ctx_cam *cam) { + ctx_images *imgs = &cam->imgs; + int width = cam->imgs.width; + int height = cam->imgs.height; + ctx_coord *cent = &cam->current_image->location; + unsigned char *out = imgs->image_motion.image_norm; + int x, y, centc=0, xdist = 0, ydist = 0; + uint64_t variance_x, variance_y, variance_xy, distance_mean; + + /* Note that the term variance refers to the statistical calulation. It is + * not really precise however since we are using integers rather than floats. + * This is done to improve performance over the statistically correct + * calculation for mean and variance + */ + cent->maxx = 0; + cent->maxy = 0; + cent->minx = width; + cent->miny = height; + variance_x=0; + variance_y=0; + distance_mean=0; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + if (*(out++)) { + variance_x += pow((x - cent->x),2); + variance_y += pow((y - cent->y),2); + /* ToDo: We should store this number for the variance calc...*/ + distance_mean += sqrt(pow((x - cent->x),2) + pow((y - cent->y),2)); + + 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 * 3; + cent->maxx = cent->x + xdist / centc * 3; + cent->miny = cent->y - ydist / centc * 3; + cent->maxy = cent->y + ydist / centc * 3; + cent->stddev_x = sqrt((variance_x / centc)); + cent->stddev_y = sqrt((variance_y / centc));; + distance_mean = (distance_mean / centc); + } else { + cent->stddev_y = 0; + cent->stddev_x = 0; + distance_mean = 0; + } + + variance_xy= 0; + out = imgs->image_motion.image_norm; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + if (*(out++)) { + variance_xy += pow( + sqrt(pow((x - cent->x),2) + pow((y - cent->y),2)) - + distance_mean, 2); + } + } + } + /* Per statistics, divide by n-1 for calc of a standard deviation */ + if ((centc-1) > 0) { + cent->stddev_xy = sqrt((variance_xy / (centc-1))); + } + +} + +/* Ensure min/max are within limits*/ +static void alg_new_location_minmax(ctx_cam *cam) { + + int width = cam->imgs.width; + int height = cam->imgs.height; + ctx_coord *cent = &cam->current_image->location; + + 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; + cent->y = (cent->miny + cent->maxy) / 2; + +} + +/* Determine the location and standard deviations of changes*/ +static void alg_new_location(ctx_cam *cam) { + + alg_new_location_center(cam); + + alg_new_location_dist(cam); + + alg_new_location_minmax(cam); + +} + +/* Apply user or default thresholds on standard deviations*/ +static void alg_new_stddev(ctx_cam *cam){ + + long chk_stddev; + /* Think about a dot in the center of the image, the distance to + * the edges is half the height/width. We can then implement a + * rule which says if the standard deviation is over a quarter of + * that distance then we have an excessive change. This is the /8 + * The above is the default if nothing is specified by the user. + */ + if (cam->conf.threshold_sdevx >0){ + if (cam->current_image->location.stddev_x < cam->conf.threshold_sdevx){ + cam->current_image->diffs = 0; + return; + } + } else { + chk_stddev = (long)((cam->imgs.width/8) - cam->current_image->location.stddev_x); + if (chk_stddev < 0) { + cam->current_image->diffs = 0; + return; + } + } + + if (cam->conf.threshold_sdevy >0){ + if (cam->current_image->location.stddev_y < cam->conf.threshold_sdevy){ + cam->current_image->diffs = 0; + return; + } + } else { + chk_stddev = (long)((cam->imgs.height/8) - cam->current_image->location.stddev_y); + if (chk_stddev < 0) { + cam->current_image->diffs = 0; + return; + } + } + + if (cam->conf.threshold_sdevxy >0){ + if (cam->current_image->location.stddev_xy < cam->conf.threshold_sdevxy){ + cam->current_image->diffs = 0; + return; + } + } else { + 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; + } + } + +} + +/* Determine base differences */ +static void alg_new_diff_base(ctx_cam *cam) { + + ctx_images *imgs = &cam->imgs; + int indx = 0; + int indx_en = imgs->motionsize; + int diffs = 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 noise) { + *out = *new_var; + diffs++; + } + out++; + ref++; + new_var++; + } + cam->current_image->diffs = diffs; + +} + +void alg_new_diff(ctx_cam *cam) { + + alg_new_diff_base(cam); + + alg_new_location(cam); + + alg_new_update_frame(cam); + + alg_new_stddev(cam); + + return; + +} diff --git a/src/alg.hpp b/src/alg.hpp index 5c3413cc..3c73e198 100644 --- a/src/alg.hpp +++ b/src/alg.hpp @@ -23,4 +23,8 @@ void alg_tune_smartmask(struct ctx_cam *cam); void alg_update_reference_frame(struct ctx_cam *cam, int); + void alg_new_update_frame(ctx_cam *cam); + void alg_new_diff(ctx_cam *cam); + + #endif /* _INCLUDE_ALG_H */ diff --git a/src/conf.cpp b/src/conf.cpp index 6a248414..4a08994d 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -193,6 +193,10 @@ struct ctx_parm config_parms[] = { "# Always save pictures and movies even if there was no motion.", 0,PARM_TYP_BOOL, PARM_CAT_02, WEBUI_LEVEL_LIMITED }, { + "primary_method", + "# Primary method to be used for detection.", + 0,PARM_TYP_INT, PARM_CAT_02, WEBUI_LEVEL_LIMITED }, + { "threshold", "# Threshold for number of changed pixels that triggers motion.", 0,PARM_TYP_INT, PARM_CAT_02, WEBUI_LEVEL_LIMITED }, @@ -201,6 +205,18 @@ struct ctx_parm config_parms[] = { "# The maximum threshold for number of changed pixels that triggers motion.", 0,PARM_TYP_INT, PARM_CAT_02, WEBUI_LEVEL_LIMITED }, { + "threshold_sdevx", + "# The maximum standard deviation of the width of motion to center.", + 0,PARM_TYP_INT, PARM_CAT_02, WEBUI_LEVEL_LIMITED }, + { + "threshold_sdevy", + "# The maximum standard deviation of the height of motion to center.", + 0,PARM_TYP_INT, PARM_CAT_02, WEBUI_LEVEL_LIMITED }, + { + "threshold_sdevxy", + "# The maximum standard deviation of the distance of motion to center.", + 0,PARM_TYP_INT, PARM_CAT_02, WEBUI_LEVEL_LIMITED }, + { "threshold_tune", "# Enable tuning of the threshold down if possible.", 0,PARM_TYP_BOOL, PARM_CAT_02, WEBUI_LEVEL_LIMITED}, diff --git a/src/conf.hpp b/src/conf.hpp index 4c226add..d43526c6 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -64,8 +64,12 @@ /* Motion detection configuration parameters */ int emulate_motion; + int primary_method; int threshold; int threshold_maximum; + int threshold_sdevx; + int threshold_sdevy; + int threshold_sdevxy; int threshold_tune; int noise_level; int noise_tune; diff --git a/src/conf_edit.cpp b/src/conf_edit.cpp index ce25292f..c3840e25 100644 --- a/src/conf_edit.cpp +++ b/src/conf_edit.cpp @@ -775,6 +775,23 @@ static void conf_edit_emulate_motion(struct ctx_cam *cam, char *arg1, enum PARM_ return; MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","emulate_motion",_("emulate_motion")); } +static void conf_edit_primary_method(struct ctx_cam *cam, char *arg1, enum PARM_ACT pact) { + int parm_in; + if (pact == PARM_ACT_DFLT){ + cam->conf.threshold = 0; + } else if (pact == PARM_ACT_SET){ + parm_in = atoi(arg1); + if ((parm_in < 0) || (parm_in > 1)) { + 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){ + conf_edit_get_int(cam->conf.primary_method, arg1); + } + return; + MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","primary_method",_("primary_method")); +} static void conf_edit_threshold(struct ctx_cam *cam, char *arg1, enum PARM_ACT pact) { int parm_in; if (pact == PARM_ACT_DFLT){ @@ -809,6 +826,57 @@ static void conf_edit_threshold_maximum(struct ctx_cam *cam, char *arg1, enum PA return; MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","threshold_maximum",_("threshold_maximum")); } +static void conf_edit_threshold_sdevx(struct ctx_cam *cam, char *arg1, enum PARM_ACT pact) { + int parm_in; + if (pact == PARM_ACT_DFLT){ + cam->conf.threshold_sdevx = 0; + } else if (pact == PARM_ACT_SET){ + parm_in = atoi(arg1); + if ((parm_in < 0) ) { + MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid threshold_sdevx %d"),parm_in); + } else { + cam->conf.threshold_sdevx = parm_in; + } + } else if (pact == PARM_ACT_GET){ + conf_edit_get_int(cam->conf.threshold_sdevx, arg1); + } + return; + MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","threshold_sdevx",_("threshold_sdevx")); +} +static void conf_edit_threshold_sdevy(struct ctx_cam *cam, char *arg1, enum PARM_ACT pact) { + int parm_in; + if (pact == PARM_ACT_DFLT){ + cam->conf.threshold_sdevy = 0; + } else if (pact == PARM_ACT_SET){ + parm_in = atoi(arg1); + if ((parm_in < 0) ) { + MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid threshold_sdevy %d"),parm_in); + } else { + cam->conf.threshold_sdevy = parm_in; + } + } else if (pact == PARM_ACT_GET){ + conf_edit_get_int(cam->conf.threshold_sdevy, arg1); + } + return; + MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","threshold_sdevy",_("threshold_sdevy")); +} +static void conf_edit_threshold_sdevxy(struct ctx_cam *cam, char *arg1, enum PARM_ACT pact) { + int parm_in; + if (pact == PARM_ACT_DFLT){ + cam->conf.threshold_sdevxy = 0; + } else if (pact == PARM_ACT_SET){ + parm_in = atoi(arg1); + if ((parm_in < 0) ) { + MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid threshold_sdevxy %d"),parm_in); + } else { + cam->conf.threshold_sdevxy = parm_in; + } + } else if (pact == PARM_ACT_GET){ + conf_edit_get_int(cam->conf.threshold_sdevxy, arg1); + } + return; + MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","threshold_sdevxy",_("threshold_sdevxy")); +} static void conf_edit_threshold_tune(struct ctx_cam *cam, char *arg1, enum PARM_ACT pact) { if (pact == PARM_ACT_DFLT){ cam->conf.threshold_tune = FALSE; @@ -2318,8 +2386,12 @@ static void conf_edit_cat02(struct ctx_cam *cam, const char *cmd, char *arg1, en } else if (mystreq(cmd,"text_scale")){ conf_edit_text_scale(cam, arg1, pact); } else if (mystreq(cmd,"text_event")){ conf_edit_text_event(cam, arg1, pact); } else if (mystreq(cmd,"emulate_motion")){ conf_edit_emulate_motion(cam, arg1, pact); + } else if (mystreq(cmd,"primary_method")){ conf_edit_primary_method(cam, arg1, pact); } else if (mystreq(cmd,"threshold")){ conf_edit_threshold(cam, arg1, pact); } else if (mystreq(cmd,"threshold_maximum")){ conf_edit_threshold_maximum(cam, arg1, pact); + } else if (mystreq(cmd,"threshold_sdevx")){ conf_edit_threshold_sdevx(cam, arg1, pact); + } else if (mystreq(cmd,"threshold_sdevy")){ conf_edit_threshold_sdevy(cam, arg1, pact); + } else if (mystreq(cmd,"threshold_sdevxy")){ conf_edit_threshold_sdevxy(cam, arg1, pact); } else if (mystreq(cmd,"threshold_tune")){ conf_edit_threshold_tune(cam, arg1, pact); } else if (mystreq(cmd,"noise_level")){ conf_edit_noise_level(cam, arg1, pact); } else if (mystreq(cmd,"noise_tune")){ conf_edit_noise_tune(cam, arg1, pact); diff --git a/src/motion_loop.cpp b/src/motion_loop.cpp index 430f66fc..bc8fcf84 100644 --- a/src/motion_loop.cpp +++ b/src/motion_loop.cpp @@ -296,7 +296,12 @@ static void mlp_init_firstimage(struct ctx_cam *cam) { } cam->current_image = &cam->imgs.image_ring[cam->imgs.ring_in]; - alg_update_reference_frame(cam, RESET_REF_FRAME); + if (cam->conf.primary_method == 0){ + alg_update_reference_frame(cam, RESET_REF_FRAME); + } else { + alg_new_update_frame(cam); + } + } @@ -906,67 +911,74 @@ static int mlp_capture(struct ctx_cam *cam){ static void mlp_detection(struct ctx_cam *cam){ if (cam->threshold && !cam->pause) { - if (cam->detecting_motion || cam->motapp->setup_mode) - cam->current_image->diffs = alg_diff_standard(cam, cam->imgs.image_vprvcy); - else - cam->current_image->diffs = alg_diff(cam, cam->imgs.image_vprvcy); + if (cam->conf.primary_method == 0){ + if (cam->detecting_motion || cam->motapp->setup_mode) + cam->current_image->diffs = alg_diff_standard(cam, cam->imgs.image_vprvcy); + else + cam->current_image->diffs = alg_diff(cam, cam->imgs.image_vprvcy); - if (cam->conf.lightswitch_percent > 1 && !cam->lost_connection) { - if (alg_lightswitch(cam, cam->current_image->diffs)) { - MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Lightswitch detected")); + if (cam->conf.lightswitch_percent > 1 && !cam->lost_connection) { + if (alg_lightswitch(cam, cam->current_image->diffs)) { + MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Lightswitch detected")); - if (cam->conf.lightswitch_frames < 1) - cam->conf.lightswitch_frames = 1; - else if (cam->conf.lightswitch_frames > 1000) - cam->conf.lightswitch_frames = 1000; + if (cam->conf.lightswitch_frames < 1) + cam->conf.lightswitch_frames = 1; + else if (cam->conf.lightswitch_frames > 1000) + cam->conf.lightswitch_frames = 1000; - if (cam->frame_skip < (unsigned int)cam->conf.lightswitch_frames) - cam->frame_skip = (unsigned int)cam->conf.lightswitch_frames; + if (cam->frame_skip < (unsigned int)cam->conf.lightswitch_frames) + cam->frame_skip = (unsigned int)cam->conf.lightswitch_frames; - cam->current_image->diffs = 0; - alg_update_reference_frame(cam, RESET_REF_FRAME); + cam->current_image->diffs = 0; + if (cam->conf.primary_method == 0){ + alg_update_reference_frame(cam, RESET_REF_FRAME); + } else { + alg_new_update_frame(cam); + } + } } - } - if (cam->conf.roundrobin_switchfilter && cam->current_image->diffs > cam->threshold) { - cam->current_image->diffs = alg_switchfilter(cam, cam->current_image->diffs, - cam->current_image->image_norm); + if (cam->conf.roundrobin_switchfilter && cam->current_image->diffs > cam->threshold) { + cam->current_image->diffs = alg_switchfilter(cam, cam->current_image->diffs, + cam->current_image->image_norm); - if ((cam->current_image->diffs <= cam->threshold) || - (cam->current_image->diffs > cam->threshold_maximum)) { + if ((cam->current_image->diffs <= cam->threshold) || + (cam->current_image->diffs > cam->threshold_maximum)) { - cam->current_image->diffs = 0; - MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Switchfilter detected")); + cam->current_image->diffs = 0; + MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Switchfilter detected")); + } } - } - cam->current_image->total_labels = 0; - cam->imgs.largest_label = 0; - cam->olddiffs = 0; + cam->current_image->total_labels = 0; + cam->imgs.largest_label = 0; + cam->olddiffs = 0; - if (cam->conf.despeckle_filter && cam->current_image->diffs > 0) { - cam->olddiffs = cam->current_image->diffs; - cam->current_image->diffs = alg_despeckle(cam, cam->olddiffs); - } else if (cam->imgs.labelsize_max) { - cam->imgs.labelsize_max = 0; /* Disable labeling if enabled */ + if (cam->conf.despeckle_filter && cam->current_image->diffs > 0) { + cam->olddiffs = cam->current_image->diffs; + cam->current_image->diffs = alg_despeckle(cam, cam->olddiffs); + } else if (cam->imgs.labelsize_max) { + cam->imgs.labelsize_max = 0; /* Disable labeling if enabled */ + } + + if ((cam->smartmask_speed && (cam->event_nr != cam->prev_event)) && + (!--cam->smartmask_count)) { + alg_tune_smartmask(cam); + cam->smartmask_count = cam->smartmask_ratio; + } + + if (cam->frame_skip) { + cam->frame_skip--; + cam->current_image->diffs = 0; + } + } else { + alg_new_diff(cam); } } else if (!cam->motapp->setup_mode) { cam->current_image->diffs = 0; } - - if ((cam->smartmask_speed && (cam->event_nr != cam->prev_event)) && - (!--cam->smartmask_count)) { - alg_tune_smartmask(cam); - cam->smartmask_count = cam->smartmask_ratio; - } - - if (cam->frame_skip) { - cam->frame_skip--; - cam->current_image->diffs = 0; - } - } static void mlp_tuning(struct ctx_cam *cam){ @@ -1005,13 +1017,21 @@ static void mlp_tuning(struct ctx_cam *cam){ /* center of motion in about the same place ? */ ((abs(cam->current_image->location.x - cam->previous_location_x)) <= (cam->imgs.width / 150)) && ((abs(cam->current_image->location.y - cam->previous_location_y)) <= (cam->imgs.height / 150))) { - alg_update_reference_frame(cam, RESET_REF_FRAME); + if (cam->conf.primary_method == 0){ + alg_update_reference_frame(cam, RESET_REF_FRAME); + } else { + alg_new_update_frame(cam); + } cam->current_image->diffs = 0; cam->lightswitch_framecounter = 0; MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("micro-lightswitch!")); } else { - alg_update_reference_frame(cam, UPDATE_REF_FRAME); + if (cam->conf.primary_method == 0){ + alg_update_reference_frame(cam, UPDATE_REF_FRAME); + } else { + alg_new_update_frame(cam); + } } cam->previous_diffs = cam->current_image->diffs; cam->previous_location_x = cam->current_image->location.x;