Skip to content

Commit

Permalink
Add threshold_maximum
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-DaveDev authored and Mr-Dave committed Oct 12, 2018
1 parent 0c806fe commit 0353dca
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 68 deletions.
10 changes: 10 additions & 0 deletions conf.c
Expand Up @@ -90,6 +90,7 @@ struct config conf_template = {
/* Motion detection configuration parameters */
.emulate_motion = FALSE,
.threshold = DEF_CHANGES,
.threshold_maximum = 0,
.threshold_tune = FALSE,
.noise_level = DEF_NOISELEVEL,
.noise_tune = TRUE,
Expand Down Expand Up @@ -655,6 +656,15 @@ config_param config_params[] = {
WEBUI_LEVEL_LIMITED
},
{
"threshold_maximum",
"# The maximum threshold for number of changed pixels that triggers motion.",
0,
CONF_OFFSET(threshold_maximum),
copy_int,
print_int,
WEBUI_LEVEL_LIMITED
},
{
"threshold_tune",
"# Enable tuning of the threshold down if possible.",
0,
Expand Down
1 change: 1 addition & 0 deletions conf.h
Expand Up @@ -75,6 +75,7 @@ struct config {
/* Motion detection configuration parameters */
int emulate_motion;
int threshold;
int threshold_maximum;
int threshold_tune;
int noise_level;
int noise_tune;
Expand Down
13 changes: 13 additions & 0 deletions motion.1
Expand Up @@ -819,6 +819,19 @@ Threshold for number of changed pixels in an image that triggers motion detectio
.RE
.RE

.TP
.B threshold_maximum
.RS
.nf
Values: 0, 1 to unlimited
Default: 0
Description:
.fi
.RS
Maximum of changed pixels in an image that triggers motion detection. A value of zero disables this option.
.RE
.RE

.TP
.B threshold_tune
.RS
Expand Down
146 changes: 83 additions & 63 deletions motion.c
Expand Up @@ -1470,6 +1470,11 @@ static int motion_init(struct context *cnt)

/* Set threshold value */
cnt->threshold = cnt->conf.threshold;
if (cnt->conf.threshold_maximum > cnt->conf.threshold ){
cnt->threshold_maximum = cnt->conf.threshold_maximum;
} else {
cnt->threshold_maximum = (cnt->imgs.height * cnt->imgs.width * 3) / 2;
}

if (cnt->conf.stream_preview_method == 99){
/* This is the depreciated Stop stream process */
Expand Down Expand Up @@ -2220,9 +2225,10 @@ static void mlp_detection(struct context *cnt){
cnt->current_image->diffs = alg_switchfilter(cnt, cnt->current_image->diffs,
cnt->current_image->image_norm);

if (cnt->current_image->diffs <= cnt->threshold) {
cnt->current_image->diffs = 0;
if ((cnt->current_image->diffs <= cnt->threshold) ||
(cnt->current_image->diffs > cnt->threshold_maximum)) {

cnt->current_image->diffs = 0;
MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Switchfilter detected"));
}
}
Expand Down Expand Up @@ -2292,26 +2298,28 @@ static void mlp_tuning(struct context *cnt){
* changes of noise_level are used.
*/
if (cnt->process_thisframe) {
if (!cnt->conf.noise_tune)
cnt->noise = cnt->conf.noise_level;

/*
* threshold tuning if enabled
* if we are not threshold tuning lets make sure that remote controlled
* changes of threshold are used.
*/
if (cnt->conf.threshold_tune)
if (cnt->conf.threshold_tune){
alg_threshold_tune(cnt, cnt->current_image->diffs, cnt->detecting_motion);
else
cnt->threshold = cnt->conf.threshold;
}

/*
* If motion is detected (cnt->current_image->diffs > cnt->threshold) and before we add text to the pictures
* we find the center and size coordinates of the motion to be used for text overlays and later
* for adding the locate rectangle
*/
if (cnt->current_image->diffs > cnt->threshold)
alg_locate_center_size(&cnt->imgs, cnt->imgs.width, cnt->imgs.height, &cnt->current_image->location);
if ((cnt->current_image->diffs > cnt->threshold) &&
(cnt->current_image->diffs < cnt->threshold_maximum)){

alg_locate_center_size(&cnt->imgs
, cnt->imgs.width
, cnt->imgs.height
, &cnt->current_image->location);
}

/*
* Update reference frame.
Expand All @@ -2321,7 +2329,9 @@ static void mlp_tuning(struct context *cnt){
* at a constant level.
*/

if ((cnt->current_image->diffs > cnt->threshold) && (cnt->conf.lightswitch_percent == 1) &&
if ((cnt->current_image->diffs > cnt->threshold) &&
(cnt->current_image->diffs < cnt->threshold_maximum) &&
(cnt->conf.lightswitch_percent >= 1) &&
(cnt->lightswitch_framecounter < (cnt->lastrate * 2)) && /* two seconds window only */
/* number of changed pixels almost the same in two consecutive frames and */
((abs(cnt->previous_diffs - cnt->current_image->diffs)) < (cnt->previous_diffs / 15)) &&
Expand Down Expand Up @@ -2424,7 +2434,8 @@ static void mlp_actions(struct context *cnt){

/***** MOTION LOOP - ACTIONS AND EVENT CONTROL SECTION *****/

if (cnt->current_image->diffs > cnt->threshold) {
if ((cnt->current_image->diffs > cnt->threshold) &&
(cnt->current_image->diffs < cnt->threshold_maximum)) {
/* flag this image, it have motion */
cnt->current_image->flags |= IMAGE_MOTION;
cnt->lightswitch_framecounter++; /* micro lightswitch */
Expand Down Expand Up @@ -2748,62 +2759,71 @@ static void mlp_parmsupdate(struct context *cnt){
/***** MOTION LOOP - ONCE PER SECOND PARAMETER UPDATE SECTION *****/

/* Check for some config parameter changes but only every second */
if (cnt->shots == 0) {

init_text_scale(cnt); /* Initialize and validate text_scale */

if (strcasecmp(cnt->conf.picture_output, "on") == 0)
cnt->new_img = NEWIMG_ON;
else if (strcasecmp(cnt->conf.picture_output, "first") == 0)
cnt->new_img = NEWIMG_FIRST;
else if (strcasecmp(cnt->conf.picture_output, "best") == 0)
cnt->new_img = NEWIMG_BEST;
else if (strcasecmp(cnt->conf.picture_output, "center") == 0)
cnt->new_img = NEWIMG_CENTER;
else
cnt->new_img = NEWIMG_OFF;
if (cnt->shots != 0) return;

init_text_scale(cnt); /* Initialize and validate text_scale */

if (strcasecmp(cnt->conf.picture_output, "on") == 0)
cnt->new_img = NEWIMG_ON;
else if (strcasecmp(cnt->conf.picture_output, "first") == 0)
cnt->new_img = NEWIMG_FIRST;
else if (strcasecmp(cnt->conf.picture_output, "best") == 0)
cnt->new_img = NEWIMG_BEST;
else if (strcasecmp(cnt->conf.picture_output, "center") == 0)
cnt->new_img = NEWIMG_CENTER;
else
cnt->new_img = NEWIMG_OFF;

if (strcasecmp(cnt->conf.locate_motion_mode, "on") == 0)
cnt->locate_motion_mode = LOCATE_ON;
else if (strcasecmp(cnt->conf.locate_motion_mode, "preview") == 0)
cnt->locate_motion_mode = LOCATE_PREVIEW;
else
cnt->locate_motion_mode = LOCATE_OFF;

if (strcasecmp(cnt->conf.locate_motion_style, "box") == 0)
cnt->locate_motion_style = LOCATE_BOX;
else if (strcasecmp(cnt->conf.locate_motion_style, "redbox") == 0)
cnt->locate_motion_style = LOCATE_REDBOX;
else if (strcasecmp(cnt->conf.locate_motion_style, "cross") == 0)
cnt->locate_motion_style = LOCATE_CROSS;
else if (strcasecmp(cnt->conf.locate_motion_style, "redcross") == 0)
cnt->locate_motion_style = LOCATE_REDCROSS;
else
cnt->locate_motion_style = LOCATE_BOX;

/* Sanity check for smart_mask_speed, silly value disables smart mask */
if (cnt->conf.smart_mask_speed < 0 || cnt->conf.smart_mask_speed > 10)
cnt->conf.smart_mask_speed = 0;

/* Has someone changed smart_mask_speed or framerate? */
if (cnt->conf.smart_mask_speed != cnt->smartmask_speed ||
cnt->smartmask_lastrate != cnt->lastrate) {
if (cnt->conf.smart_mask_speed == 0) {
memset(cnt->imgs.smartmask, 0, cnt->imgs.motionsize);
memset(cnt->imgs.smartmask_final, 255, cnt->imgs.motionsize);
}
if (strcasecmp(cnt->conf.locate_motion_mode, "on") == 0)
cnt->locate_motion_mode = LOCATE_ON;
else if (strcasecmp(cnt->conf.locate_motion_mode, "preview") == 0)
cnt->locate_motion_mode = LOCATE_PREVIEW;
else
cnt->locate_motion_mode = LOCATE_OFF;

if (strcasecmp(cnt->conf.locate_motion_style, "box") == 0)
cnt->locate_motion_style = LOCATE_BOX;
else if (strcasecmp(cnt->conf.locate_motion_style, "redbox") == 0)
cnt->locate_motion_style = LOCATE_REDBOX;
else if (strcasecmp(cnt->conf.locate_motion_style, "cross") == 0)
cnt->locate_motion_style = LOCATE_CROSS;
else if (strcasecmp(cnt->conf.locate_motion_style, "redcross") == 0)
cnt->locate_motion_style = LOCATE_REDCROSS;
else
cnt->locate_motion_style = LOCATE_BOX;

cnt->smartmask_lastrate = cnt->lastrate;
cnt->smartmask_speed = cnt->conf.smart_mask_speed;
/*
* Decay delay - based on smart_mask_speed (framerate independent)
* This is always 5*smartmask_speed seconds
*/
cnt->smartmask_ratio = 5 * cnt->lastrate * (11 - cnt->smartmask_speed);
/* Sanity check for smart_mask_speed, silly value disables smart mask */
if (cnt->conf.smart_mask_speed < 0 || cnt->conf.smart_mask_speed > 10)
cnt->conf.smart_mask_speed = 0;

/* Has someone changed smart_mask_speed or framerate? */
if (cnt->conf.smart_mask_speed != cnt->smartmask_speed ||
cnt->smartmask_lastrate != cnt->lastrate) {
if (cnt->conf.smart_mask_speed == 0) {
memset(cnt->imgs.smartmask, 0, cnt->imgs.motionsize);
memset(cnt->imgs.smartmask_final, 255, cnt->imgs.motionsize);
}

dbse_sqlmask_update(cnt);
cnt->smartmask_lastrate = cnt->lastrate;
cnt->smartmask_speed = cnt->conf.smart_mask_speed;
/*
* Decay delay - based on smart_mask_speed (framerate independent)
* This is always 5*smartmask_speed seconds
*/
cnt->smartmask_ratio = 5 * cnt->lastrate * (11 - cnt->smartmask_speed);
}

dbse_sqlmask_update(cnt);

cnt->threshold = cnt->conf.threshold;
if (cnt->conf.threshold_maximum > cnt->conf.threshold ){
cnt->threshold_maximum = cnt->conf.threshold_maximum;
} else {
cnt->threshold_maximum = (cnt->imgs.height * cnt->imgs.width * 3) / 2;
}

if (!cnt->conf.noise_tune){
cnt->noise = cnt->conf.noise_level;
}

}
Expand Down
1 change: 1 addition & 0 deletions motion.h
Expand Up @@ -399,6 +399,7 @@ struct context {

int noise;
int threshold;
int threshold_maximum;
int diffs_last[THRESHOLD_TUNE_LENGTH];
int smartmask_speed;

Expand Down
32 changes: 27 additions & 5 deletions motion_config.html
Expand Up @@ -1081,6 +1081,12 @@ <h2><a name="Configuration_OptionsAlpha"></a> Configuration Options-Listed Alph
<td align="left">threshold</td>
<td align="left"><a href="#threshold" >threshold</a></td>
</tr>
<tr>
<td height="17" align="left"></td>
<td align="left"></td>
<td align="left"></td>
<td align="left"><a href="#threshold_maximum" >threshold_maximum</a></td>
</tr>
<tr>
<td height="17" align="left">threshold_tune</td>
<td align="left">threshold_tune</td>
Expand Down Expand Up @@ -1555,28 +1561,30 @@ <h2><a name="Configuration_OptionsTopic"></a> Configuration Options-Listed by T
<tr>
<td bgcolor="#edf4f9" ><a href="#emulate_motion" >emulate_motion</a> </td>
<td bgcolor="#edf4f9" ><a href="#threshold" >threshold</a> </td>
<td bgcolor="#edf4f9" ><a href="#threshold_maximum" >threshold_maximum</a> </td>
<td bgcolor="#edf4f9" ><a href="#threshold_tune" >threshold_tune</a> </td>
<td bgcolor="#edf4f9" ><a href="#noise_level" >noise_level</a> </td>
</tr>
<tr>
<td bgcolor="#edf4f9" ><a href="#noise_level" >noise_level</a> </td>
<td bgcolor="#edf4f9" ><a href="#noise_tune" >noise_tune</a> </td>
<td bgcolor="#edf4f9" ><a href="#despeckle_filter" >despeckle_filter</a> </td>
<td bgcolor="#edf4f9" ><a href="#area_detect" >area_detect</a> </td>
<td bgcolor="#edf4f9" ><a href="#mask_file" >mask_file</a> </td>
</tr>
<tr>
<td bgcolor="#edf4f9" ><a href="#mask_file" >mask_file</a> </td>
<td bgcolor="#edf4f9" ><a href="#mask_privacy" >mask_privacy</a> </td>
<td bgcolor="#edf4f9" ><a href="#smart_mask_speed" >smart_mask_speed</a> </td>
<td bgcolor="#edf4f9" ><a href="#lightswitch_percent" >lightswitch_percent</a> </td>
<td bgcolor="#edf4f9" ><a href="#lightswitch_frames" >lightswitch_frames</a> </td>
</tr>
<tr>
<td bgcolor="#edf4f9" ><a href="#minimum_motion_frames" >minimum_motion_frames</a> </td>
<td bgcolor="#edf4f9" ><a href="#lightswitch_frames" >lightswitch_frames</a> </td>
<td bgcolor="#edf4f9" ><a href="#minimum_motion_frames" >minimum_motion_frames</a> </td>
<td bgcolor="#edf4f9" ><a href="#event_gap" >event_gap</a> </td>
<td bgcolor="#edf4f9" ><a href="#pre_capture" >pre_capture</a> </td>
</tr>
<tr>
<td bgcolor="#edf4f9" ><a href="#post_capture" >post_capture</a> </td>
</tr>

</tbody>
</table>

Expand Down Expand Up @@ -3354,6 +3362,20 @@ <h3><a name="threshold"></a> threshold </h3>
Practical values would be from a few hundred to thousands.
<p></p>

<h3><a name="threshold_maximum"></a> threshold_maximum</h3>
<p></p>
<ul>
<li> Type: Integer</li>
<li> Range / Valid values: 0, 1 to unlimited</li>
<li> Default: 0 (off)</li>
</ul>
<p></p>
This parameter specifies the maximum number of pixels that will trigger motion. When the number of
changed pixels is above the maximum, it will not trigger an event. The result is that Motion will
only trigger events when the number of pixels changes is above the threshold and less than
the threshold_maximum. A value of zero disables threshold_maximum.
<p></p>

<h3><a name="threshold_tune"></a> threshold_tune </h3>
<p></p>
<ul>
Expand Down

0 comments on commit 0353dca

Please sign in to comment.