Split motion_loop - detection

Add the motionloop_detection function
This commit is contained in:
MrDave
2016-12-04 22:35:22 -07:00
parent bbf696cd53
commit d13dafdea1
2 changed files with 124 additions and 112 deletions

231
motion.c
View File

@@ -1078,6 +1078,9 @@ static int motion_init(struct context *cnt)
cnt->minimum_frame_time_downcounter = cnt->conf.minimum_frame_time;
cnt->get_image = 1;
cnt->olddiffs = 0;
cnt->smartmask_ratio = 0;
cnt->smartmask_count = 20;
return 0;
}
@@ -1540,6 +1543,119 @@ static int motionloop_capture(struct context *cnt){
}
static void motionloop_detection(struct context *cnt){
/***** MOTION LOOP - MOTION DETECTION SECTION *****/
/*
* The actual motion detection takes place in the following
* diffs is the number of pixels detected as changed
* Make a differences picture in image_out
*
* alg_diff_standard is the slower full feature motion detection algorithm
* alg_diff first calls a fast detection algorithm which only looks at a
* fraction of the pixels. If this detects possible motion alg_diff_standard
* is called.
*/
if (cnt->process_thisframe) {
if (cnt->threshold && !cnt->pause) {
/*
* If we've already detected motion and we want to see if there's
* still motion, don't bother trying the fast one first. IF there's
* motion, the alg_diff will trigger alg_diff_standard
* anyway
*/
if (cnt->detecting_motion || cnt->conf.setup_mode)
cnt->current_image->diffs = alg_diff_standard(cnt, cnt->imgs.image_virgin);
else
cnt->current_image->diffs = alg_diff(cnt, cnt->imgs.image_virgin);
/* Lightswitch feature - has light intensity changed?
* This can happen due to change of light conditions or due to a sudden change of the camera
* sensitivity. If alg_lightswitch detects lightswitch we suspend motion detection the next
* 5 frames to allow the camera to settle.
* Don't check if we have lost connection, we detect "Lost signal" frame as lightswitch
*/
if (cnt->conf.lightswitch > 1 && !cnt->lost_connection) {
if (alg_lightswitch(cnt, cnt->current_image->diffs)) {
MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, "%s: Lightswitch detected");
if (cnt->moved < 5)
cnt->moved = 5;
cnt->current_image->diffs = 0;
alg_update_reference_frame(cnt, RESET_REF_FRAME);
}
}
/*
* Switchfilter feature tries to detect a change in the video signal
* from one camera to the next. This is normally used in the Round
* Robin feature. The algorithm is not very safe.
* The algorithm takes a little time so we only call it when needed
* ie. when feature is enabled and diffs>threshold.
* We do not suspend motion detection like we did for lightswitch
* because with Round Robin this is controlled by roundrobin_skip.
*/
if (cnt->conf.switchfilter && cnt->current_image->diffs > cnt->threshold) {
cnt->current_image->diffs = alg_switchfilter(cnt, cnt->current_image->diffs,
cnt->current_image->image);
if (cnt->current_image->diffs <= cnt->threshold) {
cnt->current_image->diffs = 0;
MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, "%s: Switchfilter detected");
}
}
/*
* Despeckle feature
* First we run (as given by the despeckle_filter option iterations
* of erode and dilate algorithms.
* Finally we run the labelling feature.
* All this is done in the alg_despeckle code.
*/
cnt->current_image->total_labels = 0;
cnt->imgs.largest_label = 0;
cnt->olddiffs = 0;
if (cnt->conf.despeckle_filter && cnt->current_image->diffs > 0) {
cnt->olddiffs = cnt->current_image->diffs;
cnt->current_image->diffs = alg_despeckle(cnt, cnt->olddiffs);
} else if (cnt->imgs.labelsize_max) {
cnt->imgs.labelsize_max = 0; /* Disable labeling if enabled */
}
} else if (!cnt->conf.setup_mode) {
cnt->current_image->diffs = 0;
}
}
//TODO: This section needs investigation for purpose, cause and effect
/* Manipulate smart_mask sensitivity (only every smartmask_ratio seconds) */
if ((cnt->smartmask_speed && (cnt->event_nr != cnt->prev_event)) &&
(!--cnt->smartmask_count)) {
alg_tune_smartmask(cnt);
cnt->smartmask_count = cnt->smartmask_ratio;
}
/*
* cnt->moved is set by the tracking code when camera has been asked to move.
* When camera is moving we do not want motion to detect motion or we will
* get our camera chasing itself like crazy and we will get motion detected
* which is not really motion. So we pretend there is no motion by setting
* cnt->diffs = 0.
* We also pretend to have a moving camera when we start Motion and when light
* switch has been detected to allow camera to settle.
*/
if (cnt->moved) {
cnt->moved--;
cnt->current_image->diffs = 0;
}
}
/**
* motion_loop
*
@@ -1550,10 +1666,7 @@ static void *motion_loop(void *arg)
{
struct context *cnt = arg;
int i, j = 0;
int smartmask_ratio = 0;
int smartmask_count = 20;
unsigned int smartmask_lastrate = 0;
int olddiffs = 0;
int previous_diffs = 0, previous_location_x = 0, previous_location_y = 0;
unsigned int passflag = 0;
long int delay_time_nsec;
@@ -1578,113 +1691,7 @@ static void *motion_loop(void *arg)
motionloop_resetimages(cnt);
if (motionloop_retry(cnt) == 1) break;
if (motionloop_capture(cnt) == 1) break;
/***** MOTION LOOP - MOTION DETECTION SECTION *****/
/*
* The actual motion detection takes place in the following
* diffs is the number of pixels detected as changed
* Make a differences picture in image_out
*
* alg_diff_standard is the slower full feature motion detection algorithm
* alg_diff first calls a fast detection algorithm which only looks at a
* fraction of the pixels. If this detects possible motion alg_diff_standard
* is called.
*/
if (cnt->process_thisframe) {
if (cnt->threshold && !cnt->pause) {
/*
* If we've already detected motion and we want to see if there's
* still motion, don't bother trying the fast one first. IF there's
* motion, the alg_diff will trigger alg_diff_standard
* anyway
*/
if (cnt->detecting_motion || cnt->conf.setup_mode)
cnt->current_image->diffs = alg_diff_standard(cnt, cnt->imgs.image_virgin);
else
cnt->current_image->diffs = alg_diff(cnt, cnt->imgs.image_virgin);
/* Lightswitch feature - has light intensity changed?
* This can happen due to change of light conditions or due to a sudden change of the camera
* sensitivity. If alg_lightswitch detects lightswitch we suspend motion detection the next
* 5 frames to allow the camera to settle.
* Don't check if we have lost connection, we detect "Lost signal" frame as lightswitch
*/
if (cnt->conf.lightswitch > 1 && !cnt->lost_connection) {
if (alg_lightswitch(cnt, cnt->current_image->diffs)) {
MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, "%s: Lightswitch detected");
if (cnt->moved < 5)
cnt->moved = 5;
cnt->current_image->diffs = 0;
alg_update_reference_frame(cnt, RESET_REF_FRAME);
}
}
/*
* Switchfilter feature tries to detect a change in the video signal
* from one camera to the next. This is normally used in the Round
* Robin feature. The algorithm is not very safe.
* The algorithm takes a little time so we only call it when needed
* ie. when feature is enabled and diffs>threshold.
* We do not suspend motion detection like we did for lightswitch
* because with Round Robin this is controlled by roundrobin_skip.
*/
if (cnt->conf.switchfilter && cnt->current_image->diffs > cnt->threshold) {
cnt->current_image->diffs = alg_switchfilter(cnt, cnt->current_image->diffs,
cnt->current_image->image);
if (cnt->current_image->diffs <= cnt->threshold) {
cnt->current_image->diffs = 0;
MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, "%s: Switchfilter detected");
}
}
/*
* Despeckle feature
* First we run (as given by the despeckle_filter option iterations
* of erode and dilate algorithms.
* Finally we run the labelling feature.
* All this is done in the alg_despeckle code.
*/
cnt->current_image->total_labels = 0;
cnt->imgs.largest_label = 0;
olddiffs = 0;
if (cnt->conf.despeckle_filter && cnt->current_image->diffs > 0) {
olddiffs = cnt->current_image->diffs;
cnt->current_image->diffs = alg_despeckle(cnt, olddiffs);
} else if (cnt->imgs.labelsize_max) {
cnt->imgs.labelsize_max = 0; /* Disable labeling if enabled */
}
} else if (!cnt->conf.setup_mode) {
cnt->current_image->diffs = 0;
}
}
/* Manipulate smart_mask sensitivity (only every smartmask_ratio seconds) */
if ((cnt->smartmask_speed && (cnt->event_nr != cnt->prev_event)) &&
(!--smartmask_count)) {
alg_tune_smartmask(cnt);
smartmask_count = smartmask_ratio;
}
/*
* cnt->moved is set by the tracking code when camera has been asked to move.
* When camera is moving we do not want motion to detect motion or we will
* get our camera chasing itself like crazy and we will get motion detected
* which is not really motion. So we pretend there is no motion by setting
* cnt->diffs = 0.
* We also pretend to have a moving camera when we start Motion and when light
* switch has been detected to allow camera to settle.
*/
if (cnt->moved) {
cnt->moved--;
cnt->current_image->diffs = 0;
}
motionloop_detection(cnt);
/***** MOTION LOOP - TUNING SECTION *****/
@@ -1997,7 +2004,7 @@ static void *motion_loop(void *arg)
if (cnt->conf.despeckle_filter) {
snprintf(part, 99, "Raw changes: %5d - changes after '%s': %5d",
olddiffs, cnt->conf.despeckle_filter, cnt->current_image->diffs);
cnt->olddiffs, cnt->conf.despeckle_filter, cnt->current_image->diffs);
strcat(msg, part);
if (strchr(cnt->conf.despeckle_filter, 'l')) {
sprintf(part, " - labels: %3d", cnt->current_image->total_labels);
@@ -2196,7 +2203,7 @@ static void *motion_loop(void *arg)
* Decay delay - based on smart_mask_speed (framerate independent)
* This is always 5*smartmask_speed seconds
*/
smartmask_ratio = 5 * cnt->lastrate * (11 - cnt->smartmask_speed);
cnt->smartmask_ratio = 5 * cnt->lastrate * (11 - cnt->smartmask_speed);
}
#if defined(HAVE_MYSQL) || defined(HAVE_PGSQL) || defined(HAVE_SQLITE3)

View File

@@ -465,6 +465,11 @@ struct context {
long int *rolling_average_data;
unsigned long int rolling_average;
int olddiffs; //only need this in here for a printf later...do we need that printf?
int smartmask_ratio;
int smartmask_count;
};
extern pthread_mutex_t global_lock;