From 4e6d3fd014143ddff7d5bc9613f8cad3d4b122f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 16:39:57 +0000 Subject: [PATCH 1/7] Initial plan From 70c47acb14312f527fc9b5b497d7851d8c6eea27 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 16:45:53 +0000 Subject: [PATCH 2/7] Add mask expansion feature to enlarge safe area around detected person Co-authored-by: umireon <1067855+umireon@users.noreply.github.com> --- data/locale/en-US.ini | 2 ++ src/background-filter.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index c2ae325d..89db8729 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -36,3 +36,5 @@ FocalBlurGroup="Focal blur settings" ThresholdGroup="Threshold settings" EnableImageSimilarity="Skip image based on similarity?" ImageSimilarityThreshold="Sim. thresh. (high -> sensitive)" +TemporalSmoothFactor="Temporal smooth factor" +MaskExpansion="Mask expansion" diff --git a/src/background-filter.cpp b/src/background-filter.cpp index c2dd1a0f..d742bd70 100644 --- a/src/background-filter.cpp +++ b/src/background-filter.cpp @@ -38,6 +38,7 @@ struct background_removal_filter : public filter_data { float contourFilter = 0.05f; float smoothContour = 0.5f; float feather = 0.0f; + float maskExpansion = 0.0f; cv::Mat backgroundMask; cv::Mat lastBackgroundMask; @@ -142,6 +143,9 @@ obs_properties_t *background_filter_properties(void *data) obs_properties_add_float_slider(threshold_props, "smooth_contour", obs_module_text("SmoothSilhouette"), 0.0, 1.0, 0.05); + obs_properties_add_float_slider(threshold_props, "mask_expansion", obs_module_text("MaskExpansion"), 0.0, 1.0, + 0.05); + obs_properties_add_float_slider(threshold_props, "feather", obs_module_text("FeatherBlendSilhouette"), 0.0, 1.0, 0.05); @@ -227,6 +231,7 @@ void background_filter_defaults(obs_data_t *settings) obs_data_set_default_double(settings, "threshold", 0.5); obs_data_set_default_double(settings, "contour_filter", 0.05); obs_data_set_default_double(settings, "smooth_contour", 0.5); + obs_data_set_default_double(settings, "mask_expansion", 0.0); obs_data_set_default_double(settings, "feather", 0.0); #if defined(__APPLE__) obs_data_set_default_string(settings, "useGPU", USEGPU_CPU); @@ -258,6 +263,7 @@ void background_filter_update(void *data, obs_data_t *settings) tf->contourFilter = (float)obs_data_get_double(settings, "contour_filter"); tf->smoothContour = (float)obs_data_get_double(settings, "smooth_contour"); + tf->maskExpansion = (float)obs_data_get_double(settings, "mask_expansion"); tf->feather = (float)obs_data_get_double(settings, "feather"); tf->maskEveryXFrames = (int)obs_data_get_int(settings, "mask_every_x_frames"); tf->maskEveryXFramesCount = (int)(0); @@ -340,6 +346,7 @@ void background_filter_update(void *data, obs_data_t *settings) obs_log(LOG_INFO, " Threshold: %f", tf->threshold); obs_log(LOG_INFO, " Contour Filter: %f", tf->contourFilter); obs_log(LOG_INFO, " Smooth Contour: %f", tf->smoothContour); + obs_log(LOG_INFO, " Mask Expansion: %f", tf->maskExpansion); obs_log(LOG_INFO, " Feather: %f", tf->feather); obs_log(LOG_INFO, " Mask Every X Frames: %d", tf->maskEveryXFrames); obs_log(LOG_INFO, " Enable Image Similarity: %s", tf->enableImageSimilarity ? "true" : "false"); @@ -559,6 +566,13 @@ void background_filter_video_tick(void *data, float seconds) backgroundMask = backgroundMask > 128; } + // Expand the mask to create a larger "safe" area around the detected person + if (tf->maskExpansion > 0.0) { + int expansion_iterations = (int)(1 + 10 * tf->maskExpansion); + cv::dilate(backgroundMask, backgroundMask, cv::Mat(), cv::Point(-1, -1), + expansion_iterations); + } + if (tf->feather > 0.0) { // Feather (blur) the mask int k_size = (int)(40 * tf->feather); From 2531963eb8866d24a40b754a7e23ac77b973b055 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 16:48:17 +0000 Subject: [PATCH 3/7] Address code review feedback: add constant for max expansion iterations Co-authored-by: umireon <1067855+umireon@users.noreply.github.com> --- src/background-filter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/background-filter.cpp b/src/background-filter.cpp index d742bd70..f45f5d1c 100644 --- a/src/background-filter.cpp +++ b/src/background-filter.cpp @@ -568,7 +568,9 @@ void background_filter_video_tick(void *data, float seconds) // Expand the mask to create a larger "safe" area around the detected person if (tf->maskExpansion > 0.0) { - int expansion_iterations = (int)(1 + 10 * tf->maskExpansion); + // Scale from 0.0-1.0 to 1-11 iterations for gradual expansion control + const int MAX_EXPANSION_ITERATIONS = 10; + int expansion_iterations = (int)(1 + MAX_EXPANSION_ITERATIONS * tf->maskExpansion); cv::dilate(backgroundMask, backgroundMask, cv::Mat(), cv::Point(-1, -1), expansion_iterations); } From 5a1a8cff613dec4f6bb9c28e7da6fa1c1cc739d0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 16:49:53 +0000 Subject: [PATCH 4/7] Follow codebase pattern: use inline magic numbers with clear comments Co-authored-by: umireon <1067855+umireon@users.noreply.github.com> --- src/background-filter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/background-filter.cpp b/src/background-filter.cpp index f45f5d1c..7645f83e 100644 --- a/src/background-filter.cpp +++ b/src/background-filter.cpp @@ -568,9 +568,8 @@ void background_filter_video_tick(void *data, float seconds) // Expand the mask to create a larger "safe" area around the detected person if (tf->maskExpansion > 0.0) { - // Scale from 0.0-1.0 to 1-11 iterations for gradual expansion control - const int MAX_EXPANSION_ITERATIONS = 10; - int expansion_iterations = (int)(1 + MAX_EXPANSION_ITERATIONS * tf->maskExpansion); + // Scale from 0.0-1.0 to 1-11 dilation iterations + int expansion_iterations = (int)(1 + 10 * tf->maskExpansion); cv::dilate(backgroundMask, backgroundMask, cv::Mat(), cv::Point(-1, -1), expansion_iterations); } From 6fa964e55a3319139d9267005f70c84b0e985d6c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 11:31:35 +0000 Subject: [PATCH 5/7] Move mask expansion slider to advanced settings (not in threshold group) Co-authored-by: umireon <1067855+umireon@users.noreply.github.com> --- src/background-filter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/background-filter.cpp b/src/background-filter.cpp index 7645f83e..0af78953 100644 --- a/src/background-filter.cpp +++ b/src/background-filter.cpp @@ -104,7 +104,7 @@ static bool enable_advanced_settings(obs_properties_t *ppts, obs_property_t *p, for (const char *prop_name : {"model_select", "useGPU", "mask_every_x_frames", "numThreads", "enable_focal_blur", "enable_threshold", "threshold_group", "focal_blur_group", "temporal_smooth_factor", "image_similarity_threshold", - "enable_image_similarity"}) { + "enable_image_similarity", "mask_expansion"}) { p = obs_properties_get(ppts, prop_name); obs_property_set_visible(p, enabled); } @@ -143,15 +143,15 @@ obs_properties_t *background_filter_properties(void *data) obs_properties_add_float_slider(threshold_props, "smooth_contour", obs_module_text("SmoothSilhouette"), 0.0, 1.0, 0.05); - obs_properties_add_float_slider(threshold_props, "mask_expansion", obs_module_text("MaskExpansion"), 0.0, 1.0, - 0.05); - obs_properties_add_float_slider(threshold_props, "feather", obs_module_text("FeatherBlendSilhouette"), 0.0, 1.0, 0.05); obs_properties_add_group(props, "threshold_group", obs_module_text("ThresholdGroup"), OBS_GROUP_NORMAL, threshold_props); + /* Mask expansion slider - in advanced settings */ + obs_properties_add_float_slider(props, "mask_expansion", obs_module_text("MaskExpansion"), 0.0, 1.0, 0.05); + /* GPU, CPU and performance Props */ obs_property_t *p_use_gpu = obs_properties_add_list(props, "useGPU", obs_module_text("InferenceDevice"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); From eca916ba525cde701bc7a50534656497bfdab1a4 Mon Sep 17 00:00:00 2001 From: Kaito Udagawa Date: Tue, 11 Nov 2025 02:41:33 +0900 Subject: [PATCH 6/7] Update background-filter.cpp --- src/background-filter.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/background-filter.cpp b/src/background-filter.cpp index 1f09f6fe..6ac25584 100644 --- a/src/background-filter.cpp +++ b/src/background-filter.cpp @@ -38,7 +38,7 @@ struct background_removal_filter : public filter_data { float contourFilter = 0.05f; float smoothContour = 0.5f; float feather = 0.0f; - float maskExpansion = 0.0f; + int maskExpansion = 0; cv::Mat backgroundMask; cv::Mat lastBackgroundMask; @@ -150,7 +150,7 @@ obs_properties_t *background_filter_properties(void *data) threshold_props); /* Mask expansion slider - in advanced settings */ - obs_properties_add_float_slider(props, "mask_expansion", obs_module_text("MaskExpansion"), 0.0, 1.0, 0.05); + obs_properties_add_int_slider(props, "mask_expansion", obs_module_text("MaskExpansion"), -30, 30, 1); /* GPU, CPU and performance Props */ obs_property_t *p_use_gpu = obs_properties_add_list(props, "useGPU", obs_module_text("InferenceDevice"), @@ -231,7 +231,7 @@ void background_filter_defaults(obs_data_t *settings) obs_data_set_default_double(settings, "threshold", 0.5); obs_data_set_default_double(settings, "contour_filter", 0.05); obs_data_set_default_double(settings, "smooth_contour", 0.5); - obs_data_set_default_double(settings, "mask_expansion", 0.0); + obs_data_set_default_double(settings, "mask_expansion", 0); obs_data_set_default_double(settings, "feather", 0.0); #if defined(__APPLE__) obs_data_set_default_string(settings, "useGPU", USEGPU_CPU); @@ -566,12 +566,13 @@ void background_filter_video_tick(void *data, float seconds) backgroundMask = backgroundMask > 128; } - // Expand the mask to create a larger "safe" area around the detected person + // Expand or shrink the mask if (tf->maskExpansion > 0.0) { - // Scale from 0.0-1.0 to 1-11 dilation iterations - int expansion_iterations = (int)(1 + 10 * tf->maskExpansion); + cv::erode(backgroundMask, backgroundMask, cv::Mat(), cv::Point(-1, -1), + tf->maskExpansion); + } else if (tf->maskExpansion < 0.0) { cv::dilate(backgroundMask, backgroundMask, cv::Mat(), cv::Point(-1, -1), - expansion_iterations); + -tf->maskExpansion); } if (tf->feather > 0.0) { From 4da99fdcfe93ac32bb6bad97ddc52887b96b9878 Mon Sep 17 00:00:00 2001 From: Kaito Udagawa Date: Tue, 11 Nov 2025 03:18:54 +0900 Subject: [PATCH 7/7] Update background-filter.cpp --- src/background-filter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/background-filter.cpp b/src/background-filter.cpp index 6ac25584..e9d36d12 100644 --- a/src/background-filter.cpp +++ b/src/background-filter.cpp @@ -569,10 +569,10 @@ void background_filter_video_tick(void *data, float seconds) // Expand or shrink the mask if (tf->maskExpansion > 0.0) { cv::erode(backgroundMask, backgroundMask, cv::Mat(), cv::Point(-1, -1), - tf->maskExpansion); + tf->maskExpansion); } else if (tf->maskExpansion < 0.0) { cv::dilate(backgroundMask, backgroundMask, cv::Mat(), cv::Point(-1, -1), - -tf->maskExpansion); + -tf->maskExpansion); } if (tf->feather > 0.0) {