Skip to content

Commit

Permalink
Allow configuration of the "variance threshold" parameter (#163)
Browse files Browse the repository at this point in the history
* fixes name of variable _learning_rate

* adds variance-threshold setting
  • Loading branch information
felixscheffer authored Jun 2, 2024
1 parent 6a2ed58 commit 0630dd5
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 5 deletions.
10 changes: 10 additions & 0 deletions docs/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,16 @@ The following options control motion detection. A more comprehensive descriptio
```
</span>
* <b><pre>variance-threshold</pre></b>
Threshold on the distance between the pixel and the model to decide whether a pixel is well described by the background model. This parameter does not affect
the background update.<br />
The threshold is not used by the CNT subtractor.
<span class="dvr-scan-default">
```
variance-threshold = 16
```
</span>
* <b><pre>kernel-size</pre></b>
Size (in pixels) of the noise reduction kernel. Size must be an odd number starting from 3, 0 to disable, or -1 to auto-set based on video resolution.
<span class="dvr-scan-default">
Expand Down
6 changes: 6 additions & 0 deletions dvr-scan.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@
# will not update the model at all, and 1.0 would re-initialize it on every frame.
#learning-rate = -1

# Threshold on the distance between the pixel and the model to decide whether
# a pixel is well described by the background model. This parameter does not affect
# the background update.
# The threshold is not used by the CNT subtractor.
#variance-threshold = 16

# Size (in pixels) of the noise reduction kernel. Can be odd integer starting
# from 3, 0 to disable, or -1 to auto-set using video resolution.
#kernel-size = -1
Expand Down
1 change: 1 addition & 0 deletions dvr_scan/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ def from_config(config_value: str, default: 'RGBValue') -> 'RGBValue':
'bg-subtractor': 'MOG2',
'threshold': 0.15,
'max-threshold': 255.0,
'variance-threshold': 16.0,
'kernel-size': KernelSizeValue(),
'downscale-factor': 0,
'learning-rate': float(-1),
Expand Down
1 change: 1 addition & 0 deletions dvr_scan/cli/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ def run_dvr_scan(settings: ProgramSettings) -> ty.List[ty.Tuple[FrameTimecode, F
detector_type=DetectorType[settings.get('bg-subtractor').upper()],
threshold=settings.get('threshold'),
max_threshold=settings.get('max-threshold'),
variance_threshold=settings.get('variance-threshold'),
kernel_size=settings.get('kernel-size'),
downscale_factor=settings.get('downscale-factor'),
learning_rate=settings.get('learning-rate'),
Expand Down
12 changes: 9 additions & 3 deletions dvr_scan/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,10 @@ def __init__(self,
# Motion Detection Parameters (set_detection_params)
self._subtractor_type = DetectorType.MOG2 # -b/--bg-subtractor
self._threshold = 0.15 # -t/--threshold
self._variance_threshold = 16.0 # variance-threshold
self._kernel_size = None # -k/--kernel-size
self._downscale_factor = 1 # -df/--downscale-factor
self._learningRate = -1 # learning-rate
self._learning_rate = -1 # learning-rate
self._max_threshold = 255.0 # max-threshold

# Motion Event Parameters (set_event_params)
Expand Down Expand Up @@ -366,6 +367,7 @@ def set_detection_params(
detector_type: DetectorType = DetectorType.MOG2,
threshold: float = 0.15,
max_threshold: float = 255.0,
variance_threshold: float = 16.0,
kernel_size: int = -1,
downscale_factor: int = 1,
learning_rate: float = -1,
Expand All @@ -379,6 +381,7 @@ def set_detection_params(
self._downscale_factor = max(downscale_factor, 1)
assert kernel_size == -1 or kernel_size == 0 or kernel_size >= 3
self._kernel_size = kernel_size
self._variance_threshold = variance_threshold
# TODO: Also allow ability to customize history size, as this is another factor that
# influences how quickly the background model is updated. When calculated automatically,
# OpenCV sets learning rate as:
Expand Down Expand Up @@ -574,16 +577,19 @@ def scan(self) -> Optional[DetectionResult]:
# Create background subtractor and motion detector.
detector = MotionDetector(
subtractor=self._subtractor_type.value(
kernel_size=kernel_size, learning_rate=self._learning_rate),
variance_threshold=self._variance_threshold,
kernel_size=kernel_size,
learning_rate=self._learning_rate),
frame_size=self._input.resolution,
downscale=self._downscale_factor,
regions=self._regions)

logger.info(
'Using subtractor %s with kernel_size = %s%s and learning_rate = %s',
'Using subtractor %s with kernel_size = %s%s, variance_threshold = %s and learning_rate = %s',
self._subtractor_type.name,
str(kernel_size) if kernel_size else 'off',
' (auto)' if self._kernel_size == -1 else '',
str(self._variance_threshold) if self._variance_threshold != 16.0 else 'auto',
str(self._learning_rate) if self._learning_rate != -1 else 'auto',
)

Expand Down
5 changes: 3 additions & 2 deletions dvr_scan/subtractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(
self,
kernel_size: int,
history: int = 500,
variance_threshold: int = 16,
variance_threshold: float = 16.0,
detect_shadows: bool = False,
learning_rate: float = -1,
):
Expand Down Expand Up @@ -93,6 +93,7 @@ def __init__(
max_pixel_stability: int = 15 * 60,
is_parallel: bool = True,
learning_rate: float = -1,
variance_threshold = None,
):
if kernel_size < 0 or (kernel_size > 1 and kernel_size % 2 == 0):
raise ValueError("kernel_size must be odd integer >= 1 or zero (0)")
Expand All @@ -118,7 +119,7 @@ def __init__(
self,
kernel_size: int,
history: int = 500,
variance_threshold: int = 16,
variance_threshold: float = 16.0,
detect_shadows: bool = False,
learning_rate: float = -1,
):
Expand Down

0 comments on commit 0630dd5

Please sign in to comment.